【零基础学数据结构】链表

 

目录

1.链表的概念

​编辑 2.链表的雏形

​编辑 3.链表的组成

​编辑 4.链表代码

 4.1创建节点

 4.2链表的打印

 4.3链表的尾插

 4.4链表的头插

 4.5链表的尾删

 4.6链表的头删

 4.7链表的查找

 4.8链表在指定位置之前插⼊数据

 4.9链表在指定位置之后插⼊数据

 4.9-1删除pos节点

 4.9-2删除pos之后的节点

4.9-3销毁链表

补充:测试文件:


1.链表的概念

 2.链表的雏形

 3.链表的组成

 4.链表代码

 创建准备;

  • SListNode.h文件
  • SListNode.c文件
  • text.c文件 

 4.1创建节点

 数据+指向下一个节点的指针

// 首先定义数据的类型,方便后续更改
typedef int SLTNodeDataType;// 创建节点
typedef struct SListNode
{SLTNodeDataType data; // 存储数据struct SListNode* next;// 指向下一个节点的指针
}SLTNode;

 4.2链表的打印

 头文件声明:

void SLTPrint(SLTNode* phead);

执行文件代码实现: 

// 链表的打印
void SLTPrint(SLTNode* phead)
{SLTNode* pcur = phead;// 保证phead指向的位置是收节点,方便后续再次遍历while (pcur)// 等价于 pcur != NULL;{printf("%d->", pcur->data);pcur = pcur->next;}printf("NULL\n");
}

 4.3链表的尾插

 头文件声明:

void SLTPushBack(SLTNode** pphead, SLTNodeDataType x);
// 创建新的节点
SLTNode* SLTBuyNode(SLTNodeDataType x)
{SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));if (NULL == newnode){perror("SLTBuyNode malloc err!");exit(1);}// 创建节点成功newnode->data = x;newnode->next = NULL;// 返回return newnode;
}

 执行文件代码实现: 

// 链表的尾插
void SLTPushBack(SLTNode** pphead, SLTNodeDataType x)
{// 传参不可为空assert(pphead);// 创建一个新的节点SLTNode* newnode = SLTBuyNode(x);// 空链表和非空链表if (*pphead == NULL){*pphead = newnode;}else{// 找尾巴SLTNode* ptail = *pphead;while (ptail->next) // 等价于ptail->next !=NULL;{ptail = ptail->next;}// 找到尾巴,开始连接ptail->next = newnode;}}

 4.4链表的头插

  头文件声明:

// 链表的头插
void SLTPushFront(SLTNode** pphead, SLTNodeDataType x);

 执行文件代码实现:

// 链表的头插
void SLTPushFront(SLTNode** pphead, SLTNodeDataType x)
{// 传参不可为空assert(pphead);// 创建一个新的节点SLTNode* newnode = SLTBuyNode(x);// 头插newnode->next = *pphead;*pphead = newnode;
}

 4.5链表的尾删

 头文件声明:

void SLTPopBack(SLTNode** pphead);

  执行文件代码实现:

// 链表的尾删
void SLTPopBack(SLTNode** pphead)
{// 链表不可以为空,传参不可为空assert(pphead && *pphead);// 链表有一个节点和多个节点// 一个节点if ((*pphead)->next == NULL){free(*pphead);*pphead = NULL;}else //多个节点{// 找尾SLTNode* prev = *pphead;SLTNode* ptail = *pphead;while (ptail->next){prev = ptail;ptail = ptail->next;}free(ptail); // 释放空间ptail = NULL;// 防止野指针prev->next = NULL;}}

 4.6链表的头删

 头文件声明:

void SLTPopFront(SLTNode** pphead);

   执行文件代码实现:

// 链表的头删
void SLTPopFront(SLTNode** pphead)
{assert(pphead && *pphead);SLTNode* next = (*pphead)->next;free(*pphead);*pphead = next;
}

 4.7链表的查找

 头文件声明:

SLTNode* SLTFind(SLTNode* phead, SLTNodeDataType x);

 执行文件代码实现:

// 链表的查找
SLTNode* SLTFind(SLTNode* phead, SLTNodeDataType x)
{SLTNode* prev = phead;while (prev)// 等价于 prev != NULL;{if (prev->data == x){return prev;}prev = prev->next;}// 遍历完毕没有找到,返回空。return NULL;
}

 4.8链表在指定位置之前插⼊数据

 头文件声明:

void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTNodeDataType x);

 执行文件代码实现:

// 链表在指定位置之前插⼊数据
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTNodeDataType x)
{// 不可以传入NULLassert(pphead && *pphead);assert(pos);// 创建一个新的节点SLTNode* newnode = SLTBuyNode(x);// 如果节点只有一个,就是头插if (pos == *pphead){SLTPushFront(pphead, x);}else{SLTNode* pcur = *pphead;// pcur所指向的节点不为pos前一个节点while (pcur->next != pos){pcur = pcur->next;}// pcur所指向的节点为pos前一个节点newnode->next = pos;pcur->next = newnode;}
}

 4.9链表在指定位置之后插⼊数据

  头文件声明:

void SLTInsertAfter(SLTNode* pos, SLTNodeDataType x);

 执行文件代码实现:

// 链表在指定位置之后插⼊数据
void SLTInsertAfter(SLTNode* pos, SLTNodeDataType x)
{assert(pos);// 创建要插入的节点SLTNode* newnode = SLTBuyNode(x);// 开始插入newnode->next = pos->next;pos->next = newnode;
}

 4.9-1删除pos节点

 头文件声明:

void SLTErase(SLTNode** pphead, SLTNode* pos);

  执行文件代码实现:

//删除pos节点
void SLTErase(SLTNode** pphead, SLTNode* pos)
{assert(pphead && *pphead);assert(pos);if (*pphead == pos){SLTPopFront(pphead);}else{SLTNode* prev = *pphead;while (prev->next != pos){prev = prev->next;}// prev所指向的就是pos前一个节点prev->next = pos->next;free(pos);pos = NULL;}}

 4.9-2删除pos之后的节点

 头文件声明:

void SLTEraseAfter(SLTNode* pos);

 执行文件代码实现:

//删除pos之后的节点
void SLTEraseAfter(SLTNode* pos)
{assert(pos && pos->next); // 传过来的参数不可以为空,pos下一个的参数也不可以是NULLSLTNode* del = pos->next;pos->next = del->next;free(del);del = NULL;
}

4.9-3销毁链表

 文件声明:

void SListDesTroy(SLTNode** pphead);

 执行文件代码实现:

//销毁链表
void SListDesTroy(SLTNode** pphead)
{assert(pphead && *pphead);SLTNode* pcur = *pphead;while (pcur){SLTNode* next = pcur->next;free(pcur);pcur = next;}// 全部销毁完后,置为空NULL;*pphead = NULL;
}

补充:测试文件:

//void SListNodeText01()
//{
//	// 创建节点
//	SLTNode* node1 = (SLTNode*)malloc(sizeof(SLTNode));
//	node1->data = 1;
//
//	SLTNode* node2 = (SLTNode*)malloc(sizeof(SLTNode));
//	node2->data = 2;
//
//	SLTNode* node3 = (SLTNode*)malloc(sizeof(SLTNode));
//	node3->data = 3;
//
//	SLTNode* node4 = (SLTNode*)malloc(sizeof(SLTNode));
//	node4->data = 4;
//
//	// 将四个节点连接起来
//	node1->next = node2;
//	node2->next = node3;
//	node3->next = node4;
//	node4->next = NULL;
//
//	// 打印
//	SLTPrint(node1);
//}void SLTNodeText02()
{//SLTNode* plist = NULL;// 测试尾插//SLTPushBack(&plist, 1);//SLTPushBack(&plist, 2);//SLTPushBack(&plist, 3);//SLTPushBack(&plist, 4);/*SLTPrint(plist);*/// 1->2->3->4->NULL;// 测试头插/*SLTPushFront(&plist, 5);SLTPrint(plist);SLTPushFront(&plist, 6);SLTPrint(plist);SLTPushFront(&plist, 7);SLTPrint(plist);SLTPushFront(&plist, 8);SLTPrint(plist);*/// 测试尾删//SLTPopBack(&plist);//SLTPrint(plist);//SLTPopBack(&plist);//SLTPrint(plist);//SLTPopBack(&plist);//SLTPrint(plist);//SLTPopBack(&plist);//SLTPrint(plist);// 测试头删//SLTPopFront(&plist);//SLTPrint(plist);//SLTPopFront(&plist);//SLTPrint(plist);//SLTPopFront(&plist);//SLTPrint(plist);//SLTPopFront(&plist);//SLTPrint(plist);// 报错//SLTPopFront(&plist);//SLTPrint(plist);// 测试查找//SLTNode* find = SLTFind(plist, NULL);//if (find == NULL)//{//	printf("没有找到!\n");//}//else//{//	printf("找到了!\n");//}// 测试在pos位置之前插⼊数据//SLTNode* find = SLTFind(plist, 1);//SLTInsert(&plist, find, 11);//SLTPrint(plist);// 测试链表在指定位置之后插⼊数据/*SLTNode* find = SLTFind(plist, 4);SLTInsertAfter(find, 11);SLTPrint(plist);*/// 测试删除pos之后的节点/*SLTNode* find = SLTFind(plist, 1);SLTEraseAfter(find);SLTPrint(plist);*/// 测试销毁SListDesTroy(&plist);
}int main()
{//SListNodeText01();SLTNodeText02();return 0;
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/310882.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python(11):网络编程

文章目录 一、一些基本概念二、软件的开发架构(c/s架构和b/s架构)三、OSI模型四、socket套接字编程1.socket编程过程2.python中的socket编程 一、一些基本概念 来了解一些网络的基本概念 名词解释IP(互联网协议地址)IP用来标识网…

基于Java+SpringBoot+vue+node.js的图书购物商城系统详细设计和实现

基于JavaSpringBootvuenode.js的图书购物商城系统详细设计和实现 🍅 作者主页 央顺技术团队 🍅 欢迎点赞 👍 收藏 ⭐留言 📝 🍅 文末获取源码联系方式 📝 🍅 查看下方微信号获取联系方式 承接各…

OpenCV——SUSAN边缘检测

目录 一、SUSAN算法二、代码实现三、结果展示 OpenCV——SUSAN边缘检测由CSDN点云侠原创,爬虫自重。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫。 一、SUSAN算法 Susan边缘检测是一种经典的边缘检测算,它由Susan Smith…

Spring Cloud+Uniapp 智慧工地云平台源码 智慧工地云平台AI视频分析应用

目录 AI应用与环境治理 设备管理与危大工程 塔吊安全监管 智慧工地APP端 智慧工地硬件设备 智慧工地主要功能模块 智慧工地可以通过以下几个方面为建筑行业赋能: 1.提高工程效率 2.提高工程安全性 3.提高工程质量 4.提高工程管理效率 绿色施工 质量管理…

面试算法-174-二叉树的层序遍历

题目 给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。 示例 1: 输入:root [3,9,20,null,null,15,7] 输出:[[3],[9,20],[15,7]] 解 class Solut…

Kubernetes(k8s):深入理解k8s中的亲和性(Affinity)及其在集群调度中的应用

Kubernetes(k8s):深入理解k8s中的亲和性(Affinity)及其在集群调度中的应用 1、什么是亲和性?2、节点亲和性(Node Affinity)2.1 硬性节点亲和性规则(required)…

【Linux】进程的优先级环境变量

个人主页 : zxctscl 如有转载请先通知 文章目录 1. 前言2. 进程的优先级2.1 什么是优先级2.2 为什么要有优先级2.3 优先级的查看方式2.4 对优先级调整 3. 命令行参数4. 环境变量4.1 环境变量与配置文件4.1.1 环境变量初步介绍4.1.2 配置文件 4.2 更多环境变量4.3 整…

SpringBoot删除菜品模块开发(SpringMVC分割参数、事务管理、异常处理、批量删除)

需求分析与设计 一:产品原型 在菜品列表页面,每个菜品后面对应的操作分别为修改、删除、停售,可通过删除功能完成对菜品及相关的数据进行删除。 删除菜品原型: 业务规则: 可以一次删除一个菜品,也可以批…

【Zabbix】zabbix 软件监控

使用zabbix监控系统查看服务器状态以及网站流量指标,利用监控系统的数据去了解上线发布的结果,和网站的健康状态 利用一个优秀的监控软件,我们可以: ●通过一个友好的界面进行浏览整个网站所有的服务器状态 ●可以在 Web 前端方便的查看监控…

MongoDB 初识

1.介绍 什么是Mong MongoDB是一种开源的文档型数据库管理系统,它使用类似于JSON的BSON格式(Binary JSON)来存储数据。与传统关系型数据库不同,MongoDB不使用表和行的结构,而是采用集合(Collection&#x…

家庭网络防御系统搭建-虚拟机安装siem/securityonion网络连接问题汇总

由于我是在虚拟机中安装的security onion,在此过程中,遇到很多的网络访问不通的问题,通过该文章把网络连接问题做一下梳理。如果直接把securityonion 安装在物理机上,网络问题则会少很多。 NAT无法访问虚拟机 security onion虚拟…

从零搭建部署最新AI系统源码ChatGPT网站AI绘画系统,图文详细搭建部署教程文档,Suno-AI音乐生成大模型

一、系统前言 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统,支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美,那么如何搭建部署AI创作ChatGPT?小编这里写一个详细图文教程吧。已支持…

(八)C++自制植物大战僵尸游戏植物基类讲解

植物大战僵尸游戏开发教程专栏地址http://t.csdnimg.cn/m0EtD 在植物大战僵尸游戏中,最重要的两个类别就是植物与僵尸。植物可以对僵尸进行攻击,不同的植物攻击方式千差万别,但是不同植物又有许多相同的属性。在基类(父类&#xf…

【C语言基础】:预处理详解(二)

文章目录 一、宏和函数的对比二、#和##运算符2.1 #运算符2.2 ##运算符 三、#undef四、命令行定义五、条件编译六、头文件的包含1. 头文件包含的方式2. 嵌套文件包含 上期回顾: 【C语言基础】:预处理详解(一) 一、宏和函数的对比 宏通常被应有于执行简单…

数图智慧零售解决方案,赋能零售行业空间资源价值最大化

数图智慧零售解决方案 赋能零售行业空间资源价值最大 在激烈的市场竞争中,如何更好地提升空间资源价值,提高销售额,成为行业关注的焦点。近日,NIQ发布的《2024年中国饮料行业趋势与展望》称,“在传统零售业态店内&…

单片机STM32中断与事件的区别

【转】1-单片机STM32---中断与事件的区别 - Engraver - 博客园 (cnblogs.com) 路径不同,处理方式不同,是否有程序不同,是否有cpu参与不同。 事件是比中断更新的升级产物。

3_2Linux中内核级加强型火墙的管理

### 一.Selinux的功能 ### 观察现象 ①当Selinux未开启时 在/mnt中建立文件被移动到/var/ftp下可以被vsftpd服务访问 匿名用户可以通过设置后上传文件 当使用ls -Z /var/ftp查看文件时显示"?" ps auxZ | grep vsftpd 时显示: - root 8546 0.0 0.0 26952 …

【QT+QGIS跨平台编译】181:【QGIS+Qt跨平台编译】—【错误处理:找不到_DEBUGA】

点击查看专栏目录 文章目录 一、找不到_DEBUGA二、原因分析三、错误处理 一、找不到_DEBUGA 报错信息: 二、原因分析 采用了非UNICODE: DEFINES - UNICODE没法识别 _DEBUGA 但可以识别 _DEBUG 三、错误处理 修改 _DEBUGA 为 _DEBUG

简单的车牌号识别

目录 处理流程与界面各接口编写时遇到的一些问题上传图片识别结果标签显示中文 处理流程与界面 首先点击“上传图片”按钮,可以选择文件夹中含有汽车车牌的图片,并显示在“图片框”中。 点击“检测车牌”按钮,会先对“图片框”中即含有汽车车…

【漏洞复现】通天星CMSV6车载视频监控平台inspect_file文件上传漏洞

Nx01 产品简介 通天星车载视频监控平台软件拥有多种语言版本,应用于公交车车载视频监控、校车车载视频监控、大巴车车载视频监控、物流车载监控、油品运输车载监控等公共交通上。 Nx02 漏洞描述 通天星CMSV6车载视频监控平台/inspect_file/upload存在文件上传漏洞&…