2.3 单链表

2.3.1 单链表的定义

什么是单链表?


typedef关键字:数据类型重命名
typedef <数据类型> <别名>
如:

  • typedef int zhengshu;
  • typedef int *zhengshuzhizhen;
  • 平时我们写的int x=1相当于zhengshu x=1;
  • 平时我们写的int *p相当于zhengshuzhizhen p;

定义单链表

  • 节点和结点的区别,视频中应该写错了,在数据结构算法中应都为结点。节点呢,被认为是一个实体,有处理能力,比如,网络上的一台计算机;而结点则只是一个交叉点,像“结绳记事”,打个结,做个标记,仅此而已,还有就是,要记住:一般算法中点的都是结点

  • 法一:先struct定义结构体再用typedef重命名

  • 法二(最简单)这里直接同时用typedef和struct,把单链表结点命名为LNode,把指向struct LNode的指针命名为*LinkList

  • struct LNode *是指向下一结点的指针,这里名字设为next;

  • 表示一个单链表时,只需声明一个头指针L

GetElem:把链表L中第i个结点取出来并返回

  • 因为要返回第i个结点,故要用LNode*来强调返回的是结点;
  • 又因为要从单链表中寻找第i个结点,故要后面的LinkList要强调这是一个单链表
  • 强调这是一个结点用LNode*
  • 强调这是一个单链表用LinkList

初始化单链表

  • 不带头结点时
  • 带头结点时,在初始化时会用malloc申请一片空间存头结点,并把地址赋给头指针L,再把next指针设为NULL,头结点不存储数据
    如果头结点之后暂时没有节点,即L->next = NULL,指向下一个指针为空,那么这个单链表就是空链表。
  • 传入指针变量时传入的是&L,带有引用&时是修改头指针L;如果不带引用&时则是修改头指针L的复制品。
  • 不带头结点和带头节点的区别

    不带头节点:头指针L指向的下一结点就是实际用于存放数据的结点。
    带头节点头指针L所指向的下一结点(头结点)是不存放实际的数据的,只有头结点的下一结点才存放数据

总结

2.3.2 单链表的插入和删除

1、按位序插入(带头结点)

ListInsert(&L, i, e)
插入操作,在表L的第i个位置上插入指定元素e。
因为是在第i个位置上插入结点,故要找到i-1个结点,再将新结点插入其后。
先找到第i-1个结点,再用malloc申请一个新的结点存入数据元素e。

  • 如果i=1则意为插在表头
  • 头结点看作是第0个结点,即j=0
  • j用来记录p当前指向哪个结点

    最坏时间复杂度为O(n):插到最后面时
    故平均复杂度为O(n),取最长时间
LNode *s = (LNode *)malloc(sizeof(LNode));
//申请新的结点空间,并用指针s指向它
s->data=e;
//把参数e存入新结点中
s->next=p->next;
//s指向结点的下一个指针next,等于p指向结点的下一个指针next
p->next=s;
//将结点s连到p之后
return true;
//插入成功

s->next=p->next;和p->next=s; 这两句顺序不能颠倒,否则指针只会指向自己
要先连接后面再连接前面

2、按位序插入(不带头结点)

ListInsert(&L, i, e) (同上)
由于不存在头结点故不存在”第0个“结点,因此i=1时需要特殊处理。
如果不带头结点,则插入,删除第1个元素时,需要更改头指针L,让L指向新的结点。

除了考虑当i=1时的情况,也就是插入第1个结点的操作与其他结点操作不同。后续逻辑和带头节点的一样。

3、指定结点的后插操作

4、指定结点的前插操作

在p结点之前插入元素e
单链表的特性:已知一个指定节点的地址,因为这个节点中只保存一个 next 指针,所以只知道后面的区域,而不知道前面的区域。
故申请一个新的结点在p指向结点的后面,新的结点再复制p结点的数据,再把e的数据放到p结点中

王道书版本中直接传入了新的要插入的结点s:

先把s连到p的后面,然后申明一个temp变量把p结点的内容保存下来,再把s的内容复制到p里面,再把temp中的内容复制s里面。

5、按位序删除(带头节点)

ListDelete(&L,i,&e):删除操作

  • 删除表L中第i个位置的元素,并用e返回删除元素的值。
  • 因为删除第i个位置的元素,故要找到i-1个结点,将其指针指向第i+1个结点,并释放第i个结点。
  • 因为要带回e,故传入时要用&e

6、指定结点的删除

bool DeleteNode(LNode p)
删除p的下一个结点q

p->data = p->next->data;
//p的数据,等于p指向的下一个结点的数据

但如果删除的是最后一个结点,这个结点指向的时NULL,那么就不存在q->next,故上面的代码就会报错(但王道书上也是这个代码)

**故这里也体现了单链表的局限性,无法逆向检索。
故这里就有了双链表,即可以双向检索的链表。
**

7、总结


封装的好处:

可以直接return使用

2.3.3 单链表的查找

1、按位查找

p刚开始指向第0个结点


王道书版本:
p刚开始指向第1个结点

封装的好处:
避免重复代码,调用即可查找

2、按值查找


平均时间复杂度:O(n)
LNode *p = L->next; // 让p指向头结点的下一个结点

3、求单链表的长度

4、总结

2.3.4 单链表的建立


1、尾插法建立单链表

  • 用malloc申请一个头结点,并把地址赋给头指针L
  • 9999是自己设置的特殊值,输入9999后结束循环
  • 设置一个表尾指针r,表尾指针从头指针开始
  • 每输入一个值时,都申请一个新的结点s,把输入的值x给s,并让r的next指针指向s
  • 再让r指针指向新的表尾结点x
  • 输入完后再让尾结点指针指空(NULL)
  • 最后return L;

2、头插法建立单链表

对头结点进行后插操作

头插法最后得到的数为输入的数的逆置,
链表的逆置!!!

注意尾插法可以不用L->next = NULL;但头插法一定要。
因为尾插法头结点指向的下一个位置的值始终会随着我们输入而变化,但头插法的头结点可能先指向某个不确定区域(脏数据),再通过s->next = L->next使得s也指向这个脏数据。
故要养成好习惯,只要是初始化单链表,都先把头指针指向NULL

2023王道考研数据结构第二章---单链表相关推荐

  1. 2023王道考研数据结构第一章---基本概念

    1.1 1.数据结构基本概念 1) 数据项.数据元素.组合项 2)数据对象 具有相同性质的数据元素的集合,是数据的一个子集. 如第一个数据对象是关于财富榜的所有数据元素的集合 第二个则是关于微博账号的 ...

  2. 【Java数据结构与算法】第二章 单链表及简单面试题

    第二章 单链表 文章目录 第二章 单链表 一.单链表 1.基本介绍 2.思路 3.代码实现 二.简单面试题 1.求单链表中有效节点的个数 2.查找单链表中的倒数第k个节点(新浪面试题) 3.单链表的反 ...

  3. 计算机组成原理笔记(王道考研) 第二章:数据的表示和运算2

    内容基于中国大学MOOC的2023考研计算机组成原理课程所做的笔记. 感谢LY,他帮我做了一部分笔记.由于听的时间不一样,第四章前的内容看起来可能稍显啰嗦,后面会记得简略一些. 西电的计算机组织与体系 ...

  4. 计算机组成原理笔记(王道考研) 第二章:数据的表示和运算1

    内容基于中国大学MOOC的2023考研计算机组成原理课程所做的笔记. 感谢LY,他帮我做了一部分笔记.由于听的时间不一样,第四章前的内容看起来可能稍显啰嗦,后面会记得简略一些. 西电的计算机组织与体系 ...

  5. (王道408考研数据结构)第二章线性表-第三节3:循环单链表和循环双链表

    文章目录 一:循环链表定义 二:循环单链表 三:循环双链表 一:循环链表定义 循环链表:规定好头尾结点的指向形成成环状 循环单链表:其尾节点的next指针由原本的空改为指向头结点 循环双链表:其尾节点 ...

  6. (王道408考研数据结构)第二章线性表-第三节1:单链表的定义及其操作(插入和删除,建立之尾插和头插)

    文章目录 一:单链表相关 (1)单链表的定义 (2)头指针与头结点 二:单链表代码描述 三:单链表的初始化 四:单链表的插入 五:单链表的删除 六:单链表查找 (1)按位查找 (2)按值查找 七:单链 ...

  7. (王道408考研数据结构)第二章线性表-第三节2:双链表的定义及其操作(插入和删除)

    文章目录 一:双链表的定义 二:双链表代码描述 三:双链表的初始化 四:双链表的插入 五:双链表的删除 一:双链表的定义 双链表:双链表在单链表的基础上再增加一个指针域,用于指向它的前驱结点 二:双链 ...

  8. 王道408数据结构——第二章 线性表

    文章目录 一.线性表的定义和基本操作 线性表 顺序表 1.插入操作 2.删除操作 3.按值查找(顺序查找) 二.单链表 1. 头插法 2. 尾插法 3. 按序号查找 4. 按值查找 5. 插入结点 6 ...

  9. 第二章——单链表和循环单链表

    线性表--链表 顺序表需要事先占用一整块实现分配大小的存储空间,但是对于某些问题:很多空间只使用一次(甚至根本用不到),使用顺序表存储空间的利用率往往很低.于是需要一种能够动态管理存储空间的存储结构- ...

最新文章

  1. 防火墙(5)——五表
  2. 嵌套矩形——DAG上的动态规划
  3. java文件编译为class文件需要键入什么命令_cmd命令行 编译Java 文件
  4. 【论文笔记】一种有效攻击BERT等模型的方法
  5. 《深入浅出DPDK》读书笔记(六):报文转发(run to completion、pipeline、精确匹配算法、最长前缀匹配LPM)
  6. IDEA搭建一个简单的Javaweb项目(二)
  7. pdfwin10闪退_win10系统打开文件夹闪退的解决方法
  8. 自定义模块的查找方式
  9. 5. 高性能MySQL --- 创建高性能索引
  10. 363.矩形区域不超过K的最大数值和
  11. JanusGraph入门实操
  12. Android Launcher研究与开发——桌面的初步定制化
  13. linux下通过关键字查询日志并定位
  14. qt中socket通信流程图_Qt学习 之 Socket通信(世界上最简单的例子了)
  15. python 对接萤石云,录制可播放的MP4视频
  16. 百度SEO站群WeLive免费在线客服系统 v5
  17. ASP 模板引擎,ASP 模板类 (Taihom.Template.class)
  18. clickhouse UI可视化工具
  19. 如何申请ios开发账号
  20. 每日一练:第十一天——侦探推理

热门文章

  1. 五:Dubbo中Provider参数配置及源码讲解
  2. c++求矩阵的秩_对于向量和矩阵的理解
  3. 关于查询报表总是“超时已过期“的问题解决
  4. 闲谈杂记:理想中智能家居App是否都可以做成分享模式
  5. linux内核printk调试手段,linux内核printk调试
  6. 待飞的蒲公英---拔剑四顾心茫然
  7. 现在是用AI给工业视觉检测赋能最好的时代
  8. echarts饼图铺满整个div
  9. 运维之思科篇 -----3.HSRP(热备份路由协议),STP(生成树协议),PVST(增强版PST)
  10. 《MVC》——ViewData、ViewBag、TempData、model