C语言加强篇——(3)学习笔记 之 链表的增、删、改、查

2023-05-16

系列文章目录

C语言加强篇——(1)学习笔记 之 变量、指针、关键字
C语言加强篇——(2)学习笔记 之 结构体、结构体指针、函数指针
C语言加强篇——(3)学习笔记 之 链表的增、删、改、查

文章目录

  • 系列文章目录
  • 一、链表
    • 1、什么是链表
    • 2、单链表
      • (1)单链表的遍历
      • (2)节点的插入
      • (3)节点的删除
      • (4)节点的修改
      • (5)节点的查找
    • 3、双链表
  • 小结


一、链表

1、什么是链表

链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列节点(链表中每一个元素称为节点)组成,节点可以在运行时动态生成。每个节点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个节点地址的指针域。

上面对链表的解释是百度百科上的解释,这看起来是不是比较难理解呢 ?接下来我带领大家来通过通俗易懂的例子来深入学习链表及链表的相关操作。

谍战片大家都看过吧,接下来将以谍战片里的某个身份来深入的学习链表;
以谍战片中的间谍来形象地表述链表。

2、单链表

间谍有自己下线间谍,每个间谍都知道怎么去找自己的下线间谍;而下线间谍不知道怎么去找他的上线间谍;他们单线联系;单线联系的间谍有个领导;
其中,领导就是头节点,最后一个间谍就是尾节点,知道怎么去找自己的下线就是指针,间谍传递的信息、指令就是数据。

也就是说这个节点,既有自己传递的信息(数据),又知道如何去找自己的下线间谍(指向下一个节点的指针)。如下图:

在这里插入图片描述

这些节点不就是我们上一篇文章中所讲述的结构体吗 !!!是的。
那么,接下来我们就可以定义一个间谍(节点)结构体:

/*间谍(节点)结构体*/

typedef struct spy {
	char name[8];         //间谍的名字
	struct spy * next;   //下一个间谍的地址,指针指向的是下一个间谍的地址
}spy, *p_spy;

定义完间谍结构体后,我们就可以来定义间谍了:

p_spy head;    //定义一个间谍的头头的地址(间谍的头头也是间谍所以定义间谍结构体指针)

/*定义间谍;在去告诉间谍他的下线的地址*/
spy spy1 = {"spy1", NULL};
spy spy2 = {"spy2", NULL};
spy spy3 = {"spy3", NULL};
spy spy4 = {"spy4", NULL};

head = &spy1;            //间谍头头的地址指向间谍1 
spy1.next = &spy2;      //spy1.next   表示间谍1的下一个间谍的地址,spy2要取地
spy2.next = &spy3;
spy3.next = &spy4;
spy4.next = NULL;     //最后一个间谍没有下线了,指向空

我们再次来看一下这个关系图:
在这里插入图片描述

这就是一个单链表,是不是这样理解起来简单多了呢 !!!

(1)单链表的遍历

我们把单链表定义出来了,当我们需要将这个链表里的数据全部打印出来时,就需要对链表进行遍历,下面是链表的遍历:


while(head)   //把头指针作为遍历链表的指针,当指针指向空时,链表结束;
{
	printf("%s\r\n", head->name);    //打印当前节点名字
	head = head->next;               //打印完成后指针指向当前的下一个结点
}

(2)节点的插入

节点的插入我们可以分为三类 :① 在链表的头部插入节点。 ② 在链表的中间插入节点。③ 在链表的尾部插入节点;我们接下来将这三类插入节点的形式封装成一个插入节点函数,废话不多说先看图解详情,再看代码能够更直观,更清晰地了解链表的插入:

原链表图解,如下图:
在这里插入图片描述
链表的插入需要先在内存中申请一个节点结构体类型的空间,将需要插入的节点信息存入申请的空间中,下面是插入不同位置的图解:

① 在链表的头部插入节点图解
在这里插入图片描述
在链表的头部插入节点就应该,先将节点1的地址给新插入节点的 next ,再让头指针 head 指向新节点。最后返回头指针。

② 在链表的中间插入节点图解
在这里插入图片描述
在链表的中间插入节点应该,先找到插入位置的前一个位置,然后将他的下一个节点地址给到新节点的next,最后将新节点的地址给前一个节点的next。

③ 在链表的尾部插入节点图解

在这里插入图片描述
在链表的尾部插入节点 与 在链表的中间插入节点是一样的,只不过一个是将空地址给新节点的next,一个是将 地址给新节点的next;

下面是插入节点函数的代码:

/**
  * @说明   调用函数 insert_spy 可以在链表的任意位置插入节点
  * @参数   head : head 是节点结构体指针类型参数,传入的值是:现有链表的头指针
  * @参数   n : n 是插入节点的位置。如:在链表头节点前插入就传入  1  ;也就是说第 n 个节点的位置是新插入的节点。
  * @返回值  返回节点结构体指针类型,返回的是头节点指针。(当在链表的头部插入需要返回新的头部节点)
  */
  
p_spy insert_spy(p_spy head, int n)
{
	int i;                           //定义 i 为了查找插入位置的前一个节点
	p_spy p, pr;                    //定义节点结构体指针 p 指向新节点,   pr 用来指向插入位置之前的节点
	p = (p_spy)malloc(sizeof(spy));  //要申请一个空间用来存放新节点,让 p 指向新建节点的地址
	
	printf("输入新节点的名字:\r\n");
	scanf("%s", p->name);           //将输入的名字存放至新节点的 name 里。
	
	pr = head;                //赋初始值,从头节点开始查找插入的位置
	i = 1;                  // i 从 1 开始循环,来寻找插入的地址
	if(n == 1 && pr != NULL)         //这个判断是用来判断是否在头节点的位置插入新节点,n == 1 是在头节点插入新节点
	{
		p->next = pr;               //依据前面图解对照写出指针的指向代码
		head = p;
	}else
	{
		while(i < n-1 && pr != NULL)   //找到插入节点的前一个节点位置
		{
			pr = pr->next;        //pr 后移,直至找到插入位置的前一个位置
			i++;
		}
		if(pr != NULL)         //插入位置的前一个位置不为空,可以是链表的末尾插入
		{           
			p->next = pr->next;   //依据前面图解对照写出指针的指向代码
			pr->next = p;
		
		}else
		{
			printf("节点不存在\r\n");   
		}
	
	}
	return head;  //返回头节点,如在头节点插入新节点,head 会变化,所以返回
}

(3)节点的删除

节点的删除和节点的插入类似 :① 在链表的头部删除节点。 ② 在链表的中间删除节点。③ 在链表的尾部删除节点;我们还是来先看图解,在看代码:

① 在链表的头部删除节点图解。
在这里插入图片描述
在链表的头部删除节点应该,将头指针 head,指向原来头节点的下一个地址,然后把原头节点所在的空间释放掉。

② 在链表的中间删除节点图解。
在这里插入图片描述
在链表的中间删除节点应该,先找到删除位置的节点以及删除位置之前节点的位置,然后让删除节点之前位置的 next 指向删除的节点的 next,最后把删除的节点空间释放掉。

③ 在链表的尾部删除节点
在这里插入图片描述
在链表的尾部删除节点 与 在链表的中间删除节点是一样的道理。

下面是删除节点函数的代码:

/**
  * @说明   调用函数 delete_spy 可以在链表的任意位置删除节点
  * @参数   head : head 是节点结构体指针类型参数,传入的值是:现有链表的头指针
  * @参数   n : n 是要删除节点的位置。如:在将链表头节点删除就传入  1  ;也就是说第 n 个节点的位置是要删除的节点。
  * @返回值  返回节点结构体指针类型,返回的是头节点指针。(当在链表的头部删除需要返回新的头部节点)
  */

p_spy delete_spy(p_spy head, int n)
{
	int i;             //定义 i 为了查找删除位置的节点
	p_spy p, pr;       // p 指向删除的节点,   pr 指向删除之前的节点
	
	pr = head;
	p = head;        //赋初始值
	i = 1;
	if(n == 1 && p != NULL)       //n == 1  说明要删除头节点
	{
		head = p->next;         //将原头节点的 next, 给新的头节点指针
		free(p);               //  free(); 释放空间函数
	}else 
	{
		while(i < n && p != NULL)   //  找到要删除的节点指针 p,,,以及要删除节点之前的节点指针 pr
		{
			pr = p;
			p = p->next;
			i++;
		}
		if(p != NULL)
		{                                 //不理解的可以对照上面图解,带入具体示例来辅助学习
			pr->next = p->next;          //将删除节点的 next 给删除节点之前的 next
			free(p);               //将删除的节点空间释放掉。
		}else 
		{
			printf("删除的节点不存在\r\n");
		}
	}
	return head;           //最后返回头指针

}


(4)节点的修改

节点的修改只需要找到要修改节点的位置,将其的数据就行修改就行了,下面直接上代码:

/**
  * @说明   调用函数 delete_spy 可以在链表的任意位置删除节点
  * @参数   head : head 是节点结构体指针类型参数,传入的值是:现有链表的头指针
  * @参数   n : n 是要修改节点的位置。如:在将链表头节点修改就传入  1  ;也就是说第 n 个节点的位置是要修改的节点。
  * @返回值  无
  */
void change_spy(p_spy head, int n)
{
	p_spy p;                  //定义要修改的节点指针 p
	int i = 1;                
	while(i < n && p != NULL)  //查找要修改的节点的位置 n
	{
		p = p->next;
		i++;
	}
	if(p != NULL)
	{
		printf("该节点的原始值为:%s\r\n", p->name);          //可以将原始值打印出来,看是否位置找的正确
		printf("请输入修改后的值:\r\n");         // 输入修改后的值
	    memset(p->name, '\0', sizeof(p->name));    //将原始值清空,防止新输入字符比原字符短,防止出现错误
		scanf("%s", p->name);                  
	}else
	{
		printf("该节点不存在\r\n");
	}
}

(5)节点的查找

在学习完链表的增加、删除、修改后,节点的查找就不用再去仔细的详解了,请看上面代码。

3、双链表

对比单链表,双链表就是节点既有下一个节点的地址,又有上一个节点的地址,其双链表图解如下:
在这里插入图片描述
对比单链表的各种操作我们也不难写出双链表对应的函数,在这里就不详细写双链表了。


小结

本文主要写单链表的遍历以及增、删、改、查的操作。感谢大家观看

本专栏文章:
C语言加强篇——(1)学习笔记 之 变量、指针、关键字
C语言加强篇——(2)学习笔记 之 结构体、结构体指针、函数指针
C语言加强篇——(3)学习笔记 之 链表的增、删、改、查

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C语言加强篇——(3)学习笔记 之 链表的增、删、改、查 的相关文章

  • 字符串查找函数Strstr函数的实现(详细易懂)

    首先 xff0c 字符串查找函数是在目的字符串中查找源字符串的首次出现的具体位置 xff0c 若找到了便返回该位置的地址 xff0c 若没有找到 xff0c 则返回空指针NULL char strstr const char arr1 co
  • ROS安装与Rviz的摄像头视频采集与标定

    文章目录 一 ROS的安装与配置1 添加 ROS 软件源 xff0c 将下列命令输入到 Ubuntu 的终端执行2 添加密钥 xff0c 将下列命令输入到 Ubuntu 的终端执行3 安装desktop full4 初始化rostep5 设
  • ros2的基本使用/基础知识——ros2节点

    1 节点是什么 每个节点只负责单独的模块 xff08 例如 xff1a 控制车轮转动 xff1b 从激光雷达处获得数据 xff1b 处理激光雷达的数据 xff1b 负责定位 xff09 照相机 地盘 控制 2 节点之间如何交互 xff1f
  • SSH秘钥登录配置与系统日志管理

    配置 sshd 服务 SSH xff08 Secure Shell xff09 是一种能够以安全的方式提供远程登录的协议 xff0c 也是目前远程管理 Linux 系统 的首选方式 在此之前 xff0c 一般使用 FTP 或 Telnet
  • 关于Ubuntu中Could not get lock /var/lib/dpkg/lock解决方案

    问题现象 xff1a root 64 gvt NUC6CAYH apt get install net tools E Could not get lock var lib dpkg lock frontend open 11 Resour
  • vscode报错vue/multi-word-component-names处理

    vue multi word component names是用于检测当前的组件名称是否使用驼峰或多单词命名 错误截图如下 xff1a 1 可以修改 eslintrc js文件的配置 module exports 61 root true
  • Android SDK的安装步骤

    1 Android SDK下载 https www androiddevtools cn 2 解压Android SDK压缩包 放在没有中文的目录里面 3 打开Android sdk windows文件夹 xff0c 双击SDK manag
  • Apollo control之PID算法

    Apollo studio 官网 xff1a Apollo开发者社区 baidu com 目录 1 PID简介 2 PID调参思路 3 代码 4 解决积分饱和的方法 4 1 IC 积分遇限削弱法 4 2 BC 反馈抑制抗饱和 1 PID简介
  • TCP通信模型(C语言实现)

    大家好 xff0c 我是练习编程时长两年半的个人练习生昆工第一ikun xff0c 今天我们来分享TCP通信模型 xff0c 并且用C语言实现它 目录 一 我们将实现三个示例功能 xff1a 二 TCP服务器搭建流程 xff08 1 xff
  • 场景文本识别中的字符感知采样与校正(Character-Aware Sampling and Rectification for Scene Text Recognition)

    摘要 由于形状和纹理变化较大 xff0c 曲面场景文本识别在多媒体社会中是一项具有挑战性的任务 以前的方法通过等距离采样提取和校正文本行来解决这一问题 xff0c 这忽略了字符级别信息并导致字符失真 为了解决这个问题 xff0c 本文提出了
  • MyBatisPlus中的likeLeft和likeRight

    在使用MyBatisPlus来匹配身份证后6位时遇到了likeLeft和likeRight的问题 xff1a likeLeft时匹配最左边还是匹配最右边 xff1f 所以来一个简单的测试 xff08 通过打印 成功 失败 来判断 xff09
  • 计算机网络第一章总结

    目录 1 1计算机网络再信息时代中的作用 1 2互联网的概述 1 2 1网络 xff0c 互联网和因特网 1 2 2互联网基础结构的三个阶段 1 2 3互联网的标准化工作 1 3互联网的组成 1 3 1三种交换方式 1 4计算机网络的类别
  • Expression #3 of SELECT list is not in GROUP BY clause and contains nonaggregated column……报错的解决办法

    问题原因 xff1a 这个报错是执行有GROUP BY的语句时出现的 原因是MySQL启用了默认的only full group by SQL模式 导致GROUP BY语句报错 解决办法 xff1a 打开mysql的安装目录找到my ini
  • 【Linux安全管理】Firewalld详解

    目录 1 与iptables不同 2 配置防火墙 3 firewalld区域概念 4 filewalld 配置生效 5 firewalld服务 firewalld 端口映射 富规则 rich rule 1 与iptables不同 firew
  • C++之class和struct的区别

    在C语言中 xff0c struct是一个数据类型 xff0c 所以struct内不能定义函数 xff1b 在C 43 43 中保留了struct关键字 xff0c 并且进行了补充 xff0c struct类似于class xff0c 可以
  • QEMU使用virtio磁盘(Ubuntu/windows)

    环境 宿主环境 xff1a windows 10 pro QEMU版本 xff1a 3 1 客户机 xff1a windows2003 virtio是一种半虚拟化技术 xff0c window2003安装盘不带驱动程序 xff0c 所以首先
  • 创建一个ArrayList<String> 集合,通过反射向集合中添加Integer类型的数据

    1 思路 创建一个ArrayList lt String gt 集合 通过反射获取到ArrayList的Class对象通过Class类获取到ArrayList中的add方法 2 所需关键知识 获取Class类有三种方法 xff1a xff0
  • Git分支&标签

    目录 一 xff0c 分支 环境的的功能及特点 分支的策略 分支的相关指令 二 xff0c 标签 1 查看所有标签 2 创建tag 3 删除tag 4 分支与版本 一 xff0c 分支 1 分支的命名规范 dev test pre pro
  • java酒店管理系统小型项目

    前言 学习java这段时间以来 xff0c 给我的感觉是非常枯燥和乏味的 xff0c 因为学习编程这个过程就是这样 xff0c 除此之外我是自学 xff0c 所以遇到问题只能自己上网找资料 xff0c 或者看一些大佬的文章来解决问题 不过学
  • 基于智能优化算法的无人机路径规划(Matlab代码实现)

    目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码实现 1 概述 无人机作为一种现代航空设备 不仅作业速度快 成本低 还具有卓越的灵活性和时效性 常用于完成那些繁冗 危险 对灵活性要求较高 作业范围较大的任务 比如航空拍摄 农

随机推荐

  • 布谷鸟搜索算法的改进及其在优化问题中的应用(Matlab代码实现)

    x1f352 x1f352 x1f352 欢迎关注 x1f308 x1f308 x1f308 x1f4dd 个人主页 xff1a 我爱Matlab x1f44d 点赞 评论 收藏 61 61 养成习惯 xff08 一键三连 xff09 x1
  • 基于MATLAB中雷达和视觉合成数据的目标级传感器融合(Matlab)代码实现

    目录 x1f4a5 1 概述 x1f4da 2 运行结果 x1f389 3 参考文献 x1f468 x1f4bb 4 Matlab代码 x1f4a5 1 概述 本文使用MATLAB的场景生成器工具箱 xff0c 通过合成雷达和视觉观察创建一
  • Linux嵌入式开发——C编程

    文章目录 Linux嵌入式开发 C编程一 编写C程序1 1 设置vim编辑器1 2 编写C程序 二 编译C程序三 make工具和Makefile文件3 1 编写C程序C文件H文件 3 2 不使用make工具3 3 使用make工具和Make
  • C#中的接口

    一 什么是接口 含义 xff1a 接口是指定一组函数成员而不实现它们的引用类型 xff08 只能用类和结构实现接口 xff09 接口可以包含实例方法 属性 事件 索引器或这四种成员类型的任意组合 接口可以包含静态构造函数 xff08 不能创
  • VINS-MONO工程改造

    这篇是接着前文 主流VIO VSLAM系统改造与工程化落地 和 关于VIO零速更新 ZUPT 与控制三种约束的工程实践 的 xff0c 有时候想一出是一出 xff0c 导致写的东西还是太分散了 要做VINS改造首先要熟悉VSLAM和数学基础
  • DM-VIO简析

    今天主要是针对DMVIO DM VIO的简析 xff0c 中文网上有的东西都太少了 xff0c 只能靠看完论文和组员们一起改代码 Lukas组这个东西在中文网被称为有史以来最好的VIO xff0c 但是实际过程中我们还是发现了许多不完美的地
  • Hao to setup windbg on windows10 LTSC img

    Windows host Debugger install windbg https developer microsoft com en us windows downloads windows 10 sdk download the i
  • VINS/VIO的并行化与工程化(GPU篇)

    最近更新的这2篇应该是比较重的了 xff0c 先做GPU篇 xff0c 再做DSP篇 先友情提醒 xff0c 这篇文章很重很费时 xff0c 对各种软硬算的知识要求多多 主体知识来源于UZH和ETH的研究者Balazs Nagy组 xff0
  • 关于机器人状态估计8-VSLAM工程与VIO工程难点

    最近做产设和综述把头都整晕了 xff0c 本来想认真更新GPU那篇DSP的姊妹篇 xff0c 突然觉得太长了实在是没有写的欲望 xff0c 还是写篇杂文算了 一看这个标题就知道 首先如果没有 关于机器人状态估计 4 成长路径与能力提升这块基
  • VIO/VINS/VSLAM问题定位流程与思路

    首先假设读者是了解基础VSLAM xff0c 了解VIO基础 至少要会标定 xff0c 调过几个开源系统的 先说一下双目的VINS FUSION xff0c 大部分问题都是基线造成的问题 xff0c 简单点说就是如果使用较短的基线如5cm
  • VIO/VINS中关于能观性/可观性的详细讲解

    以前大概写过一下 xff0c 太烂了 也是没什么人写 xff0c 再详细讲解一下 整体简洁一点尝试主要用文字说明这个比较关键的点 xff0c 其实整体和多传感器融合也有很大的关联 xff0c 无论是外感还是内感传感器 xff0c 无外乎从运
  • 关于机器人状态估计(10)-VSLAM与VIO的3D建图,重定位与世界观综述

    近期我国迎来了cov海啸 xff0c 其实我也不知道我羊了没有 xff0c 但并没有什么不舒服同时因为我没有测 xff0c 那自然是没有羊 xff0c 或者是薛定谔的羊 近年另外一块工作的综述 xff0c 这篇科普的同时 xff0c 也会包
  • 关于机器人状态估计(11)-VIO单目与双目/雷达Lidar SLAM/未来的机器人

    写这篇文章的时候刚发生行业大事件 xff1a Google收购ROS 其实一开始还是水 xff0c 绝对大量文不对题 xff0c 但是必有干货 xff0c 毕竟用的是这个关键的系列标题 最近有几件行业内发生的大小事 xff0c 让我觉得有必
  • Javaer都在用的Java后端面试笔记, 涵盖90%的主流技术,啃完分分钟拿下大厂offer!!

    到底该如何准备高级开发 架构师级别的面试 xff1f 为了帮助有需要的朋友在金九银十面试 xff0c 最近整理了一份面试知识点笔记复习资料 xff0c 内容包含 xff1a JVM xff0c JAVA多线程并发 xff0c Spring
  • 防火墙---firewalld

    Firewalld概述 支持网络区域所定义的网络链接以及接口安全等级的动态防火墙管理工具支持IPv4 IPv6防火墙设置以及以太网桥支持服务或应用程序直接添加防火墙规则接口拥有两种配置模式 xff1a 运行时配置永久配置 firewalld
  • Linux系统的初次使用

    在linux中安装JDK 1 安装xftp7 从windows上传输一个JDK到Linux中 opt apps下 2 对 opt apps下的JDK压缩包进行解压 tar zxvf jdk 8u191 linux x64 tar gz 3
  • C语言加强篇——(1)学习笔记 之 变量、指针、关键字

    系列文章目录 C语言加强篇 xff08 1 xff09 学习笔记 之 变量 指针 关键字 C语言加强篇 xff08 2 xff09 学习笔记 之 结构体 结构体指针 函数指针 C语言加强篇 xff08 3 xff09 学习笔记 之 链表的增
  • linux/unix系统下IOZONE/iozone磁盘性能测试工具方法

    IOZONE主要用来测试操作系统文件系统性能的测试工具 xff0c 该工具所测试的范围主要有 xff0c write Re write Read Re Read Random Read Random Write Random Mix Bac
  • C语言加强篇——(2)学习笔记 之 结构体、结构体指针、函数指针

    系列文章目录 C语言加强篇 xff08 1 xff09 学习笔记 之 变量 指针 关键字 C语言加强篇 xff08 2 xff09 学习笔记 之 结构体 结构体指针 函数指针 C语言加强篇 xff08 3 xff09 学习笔记 之 链表的增
  • C语言加强篇——(3)学习笔记 之 链表的增、删、改、查

    系列文章目录 C语言加强篇 xff08 1 xff09 学习笔记 之 变量 指针 关键字 C语言加强篇 xff08 2 xff09 学习笔记 之 结构体 结构体指针 函数指针 C语言加强篇 xff08 3 xff09 学习笔记 之 链表的增