一、线性表
1.定义
相同类型的数据元素构成的有限序列
①n为表长,n=0时为空表。
②ai是线性表中第i个元素在线性表中的位序,位序从1开始,数组下标从0开始。
2.基本操作
①初始化表。
②销毁。
③插入。
④删除。
⑤按值查找。
⑥按位查找。
注意:当传入函数的参数的改变需要带回主函数时,要使用引用参数方式。
二、顺序表
1.定义
顺序存储的线性表。
2.顺序表的实现
注意初始化数据元素的初始值,否则可能指向遗留的脏数据。
①静态分配
②动态分配:注意malloc返回的指针要强制转换成与数据同类型的指针。
3.特点
①随机访问,O(1)。
②存储密度高。
③拓展容量不方便。
④插入、删除数据元素不方便。
4.插入和删除
①插入的位置[1,length+1]
②判断线性表是否已满,无论是静态还是动态,都有一个maxsize。
①删除范围[1,length]。
②注意返回被删除的元素e。
③移动元素时要注意不要覆盖掉已有的元素。
④插入和删除元素都需要引用参数。
5.查找
①按位查找(顺序表采用顺序存储,可以使用数组下标来查找)
静态分配
动态分配
②按值查找(结构类型值的比较,应该自己写一个函数或者重载==来进行值的比较)
动态分配
三、链表
1.单链表
1.1定义
①定义
|数据元素 | 指向下一个节点的指针|
②不支持随机存储
③typedef <数据类型><别名>
④LNode和*LinkList指的是同一个类型,只是Node强调的是节点,*LinkList强调的是链表
⑤不带头结点的单链表
⑥带头结点的单链表
1.2插入与删除
①带头结点的按位序插入
②不带头结点的按位序插入
③指定节点的后插操作
④指定节点的前插操作
方式一:利用头指针
方式二:数据跑路(创建一个新结点s,s存放p节点的数据,把要插入的节点e的数据赋值给p节点)
1.3查找(带头结点的)
①按位查找
②按值查找
③求单链表长度
1.4尾插法与头插法构建单链表(核心都使用了后插操作)
①尾插法
方法一:没有尾指针时,需要从头开始扫描
方法二:有尾指针时,每次插入都需要移动指针
②头插法(可应用于链表的逆置)
2.双链表
2.1初始化(带头结点)
2.2插入
2.3删除
2.4遍历
3.循环链表
3.1循环单链表
①初始化
3.2循环双链表
①初始化:
②插入
③删除
4.静态链表
①定义
|数据元素 |下一个节点的数组下标(游标)|
用数组方式实现的链表。
分配一整片连续的内存空间安置各个节点。
SLinkList a;即自动生成一个大小为10的数组。
等价于 Node a[MaxSize];
②查找、插入与删除。注意next赋初始值赋为-2,代表此节点是空闲的。
可以把静态链表当中的游标映射成所对应节点的实际存放位置。
四、顺序表与链表对比
1、逻辑结构
均为线性表,线性结构,一对一。
2.存储结构
①顺序表支持随机存取,存储密度高。但是大片连续空间分配不方便,改变容量不方便。
②链表离散的小空间分配方便,改变容量方便。但是不可随机存取,存储密度低。
3.基本操作
①创建
顺序表的静态分配和动态分配;链表的动态分配。(其实我觉得静态链表就是链表的静态分配,但是不知道为什么特意开了一个章节。虽然开了一个章节但是讲的也不是很详细)
②销毁
静态分配系统自动回收,动态分配用free释放。
③增删
④查找
⑤总结