第二章 线性表
定义(Linear List)
线性表时具有相同数据类型的n个数据元素的有限序列,其中n为表长,当n=0时,线性表是一个空表。
几个概念:
- 表长、空表
- 表头、表尾
- 前驱、后继
- 数据元素的位序是从1开始的;数组下标从0开始
为什么要实现对数据结构的基本操作?
①团队合作编程,你定义的数据结构要让别人能够很方便的使用(封装)
②将常用的操作/运算封装成函数,避免重复工作,降低出错风险
操作
基本操作
-
创销、增删改查
-
判空、判长、打印输出
-
其他要注意的点
-
什么时候需要传入参数的引用“&”
- 对参数修改结果需要带回来的时候
-
逻辑结构
存储/物理结构
顺序表(顺序存储)
-
用顺序存储的方式实现线性表顺序存储,把逻辑上相邻的元素存储在物理位置上也相邻的存储单元中,元素之间的关系由存储单元的邻接关系来体现
-
实现方式
-
静态分配
-
-
- 使用“静态数组”实现
- 大小一旦确定就无法改变
- 动态分配
-
- 使用“动态数组”实现
- **L.data = (ElemType *) malloc (sizeof(ElemType) * InitSize);**
- **顺序表存满时,可再用malloc动态拓展顺序表的最大容量**
- **需要将数据元素复制到新的存储区域,并用free函数释放原区域**
-
- 顺序表的特点:
- **①随机访问,即可以在 O(1) 时间内找到第 i 个元素。**
- **②存储密度高,每个节点只存储数据元素**
- **③拓展容量不方便(即便采用动态分配的方式实现,拓展长度的时间复杂度也比较高)**
- **④插入、删除操作不方便,需要移动大量元素**
-
-
顺序表的基本操作
-
插入
-
ListInsert(&L,i,e)
- 将元素e插到L的第i个位置,插入位置之后的元素都要后移
-
- 代码实现
- 时间复杂度
-
删除
-
ListDelete(&L,i&e)
- 将L的第i个元素删除,并用e返回
- 删除位置之后的元素都要前移
-
- 时间复杂度:-
-
查找
-
按位查找
-
代码实现
-
GetElem(L,i)按位查找操作,获取表L中第i个位置的元素的值
-
-
- 用数组下标即可得到第i个元素L.data[i-1]-
时间复杂度
-
-
- 按值查找 - 代码实现 - **LocateElem(L,e):按值查找操作。在表L中查找具有给定关键字值的元素。** - ![image](https://img-blog.csdnimg.cn/img_convert/ccc629c410736c112c1dada76d86484c.png) - ![image](https://img-blog.csdnimg.cn/img_convert/ee0f29ec9088d22ed59361a86ca1ebb3.png) - ![image](https://img-blog.csdnimg.cn/img_convert/a0cb8c75da8c90dab65d816ec5873553.png) - **在顺序表L中查找第一个元素值等于e的元素,并返回其位序** - **在第一个元素开始依次往后检索** - 时间复杂度 -
-
代码要点
-
注意位序i和数组下标的区别
-
算法要有健壮性,注意判断i的合法性
-
移动元素时,从靠前的元素开始,还是从表尾元素开始
-
为什么又的参数需要加“&”引用
- 如果不加&,则被调用函数中处理的是参数数据的复制品
-
-
链表(链式存储)
-
单链表
-
定义
-
用链式存储(存储结构)实现了“线性结构”(逻辑结构)
-
- 一个结点存储一个数据元素 - 各结点间的先后关系关系用一个指针表示 -
-
- 带头结点和不带头结点的- 不带头结点的单链表 -
- 空表判断:L==NULL- 带头结点的单链表 -
- 空表判断:L->next==NULL- 区别 - **不带头结点,写代码更麻烦
对第一个数据结点和后续数据结点的
处理需要用不同的代码逻辑
对空表和非空表的处理需要用不同的
代码逻辑**
-
- 其他注意的点 - typedef关键字的用法 - “LinkList”等价于“LNode”
前者强调这是链表,后者强调这是结点‘
-
插入
-
按位序插入
-
带头结点
-
ListInsert(&L,i,e):插入操作。在表L中的第i个位置上插入指定元素e。
-
-
- 顺序不能颠倒
- 如果插入位置为表头元素,最好时间复杂度O(1),最坏时间复杂度O(n)-
不带头结点
-
-
-
- 指定结点的后插操作 -
-
- 指定结点的前插操作 -
-
-
-
删除
-
按位序删除
-
ListDelete(&L,i,&e):删除操作。删除表L中第i个位置的元素,并用e返回删除元素的值。
-
-
-
- 指定结点删除 - ![image](https://img-blog.csdnimg.cn/img_convert/36286ad6bac3b0f9e891ef23d625e367.png) - ![image](https://img-blog.csdnimg.cn/img_convert/59b1d4bdc22e998d3d128d9686a45e74.png) -
-
查找
-
按位查找
-
注意与顺序表的对比
- 单链表不具备随机访问的特性,只能一次扫描
-
GetElem(L,i):按位查找操作。获取表L中第i个位置的元素的值。
-
-
按值查找
- LocateElem(L,e):按值查找操作。在表L中查找具有给定关键字值的元素。
-
求单链表长度
-
关键点
- 三种基本操作的时间复杂度都是O(n)
- 如何写循环扫描各个结点的代码逻辑
- 注意边界条件的处理
-
-