这里写目录标题
链式存储结构
链表
简介
格式
案例
开头是头指针H 指向第一个数据元素的数据域,之后第一个数据元素的指针域指向第二个元素的数据域,由此连接成一个链表,最后末端是一个空指针,记作“^”
分类
头结点
位置
头指针只是一个指针域,没有数据域,头结点有数据域和指针域
示意图
与不带头结点的区别
数据域任意存放数据,可以用来存放线性表的长度等信息,但是头结点不计入链表的长度值
链表的特点
单链表
定义
链表的代码实现
简介
首先,对于一个结点来说,包含两个东西,一个是数据域,一个是指针域,用代码实现一个结点的时候,要用结构体,
第二,结构体里面,对于数据域的定义,使用表中的数据类型对应即可,对于指针域,因为其指向的是下一个结点,而每个结点都是一个结构体,所以,指针的类型是结构体类型,与自己所在的结构体一模一样
第三,typedef 是对后面圈起来的结构体起别名,相当于Java中对一个类起了一个别名,后面的Lnode 以及 *LinkList都是结构体的别名,二者是两种不同的形式
对于Lnode,可以直接利用它来定义一个对象,之后利用该对象调用结构体中的数据,这样这个对象就是结点本身
也可以,定义一个该类型的指针,用指针来操作结构体中的数据,这样指针就是指向结点的,如下图
而对于定义指针可以有更简便的方法,因为还定义了一个别名 是 *LinkList,所以可以直接,LinkList p
如下图
实操
定义链表,以及定义结点时,通常采用图中黄色部分
注意别忘了,头指针表示整个链表
右边为统一的定义方式,将所有数据打包为一个结构体,之后直接定义结构体类型的数据域
基本操作的实现
初始化单链表
空表定义,对于引用类型的参数,详情见上一篇文章“补充”,大致是,形参和实参共用一个地址
销毁单链表
首先将头指针的值赋值给结点指针p,之后要把第一个结点的指针域赋值给头指针L,以便L可以下移,找到下一个结点
之后销毁第一个结点,再把L的值赋给p,L再下移,这样循环,就可以销毁单链表
清空单链表
思路与销毁差不多,只不过新定义了一个指针,用来代替销毁时的L,这时L保持不动,用于保留头指针和头结点,最后将头结点的指针域置空即可
循环顺序与销毁有所不同,这里顺序不同,一定程度上影响着循环条件的判断,具体问题具体分析即可
求单链表表长
注意,p所指向的是一个结点,所以,p有值,那么就表示有结点,最后p指向空的时候,就会跳出循环
注意 头结点不计入长度,长度从首元结点算起
取值
算法分析
注意第15个元素不存在,这里有异常情况的处理
计数器很重要,用来记录当前的结点位置
算法设计
查找
算法思路
算法实现
注意,&&是逻辑与的意思,假:一假全假,真:全真才为真
||是逻辑或的意思,真:一真全真,假:全假才为假
当返回当前位置时,加个计数器即可
插入
注意执行的先后顺序,可能会导致数据的丢失
这里循环条件判断,p不为空,并且要j<i-1,注意 相对于 j !=i-1,j<i-1 更为严谨,因为i-1的值是直接输入,可能初值就比j要大
之后做一个条件判断,处理异常情况
之后创建一个新结点,创建时,利用指针创建,也就是创建指针形式的新结点,这样,新结点的地址也就有了
删除
参数列表中,&L 以及 &e 都是采用引用类型,作用是与主函数里的实参,保持共用一片地址,这样无需做其他任何的操作,直接就可以将操作后的结果同步到主函数的实参,相当于完成了函数的返回
while中的条件作用是,p指针将要下移的元素存在,并且要删除的元素的位置是存在的
if的判断是删除的位置超过长度以及小于第一个结点的位置,的处理
查找、插入、删除算法的效率分析
单链表的建立(创建出一个带值的单链表)
头插法
采用倒序,从最后一个元素开始依次插入
第一步注意,创建一个空表,注意将第一个结点的指针域置空
之后,创建一个新结点,输入该结点的数据域,并且将该结点的指针域换成头结点的指针域(也就是将原来的链表除头结点外,都插入到新结点的后面),之后,将新结点的指针,交给头结点的指针域
尾插法
循环链表
定义以及格式
判断终止条件是 指针是否指向头结点
一般对于”操作多在首位以及尾部时“的需求,会采用循环链表,并加上一个尾指针,利用尾指针操作,这样可以提高效率
合并两个循环链表
注意保存Ta的头结点
双向链表
定义
头结点的前驱指针域为空,最后一个结点的后继指针域也为空
双向链表也可以有循环
将链表头结点和尾结点看成相邻的结点,之后对应的指针域指向对应的结点即可
对于双向链表有一些操作可以直接看成一个方向上的单链表进行操作,对于插入、删除 操作时,则需要有特别的操作
插入算法
第一步 先找到对应位置的指针p(利用之前单链表的算法)
第二部 需要对新结点的两个指针域都进行两个方向的操作
这里注意 对于 p->next 既指下一个结点的指针,又指当前结点的后继指针域,二者划等号
当对p->next赋值时,是指当前结点的指针域