线性表(linear list)
定义
- n个数据元素的有限序列
特点
- 同一线性表中元素具有相同特性。
- 相邻数据元素之间存在序偶关系。
- 除第一个元素外,其他每一个元素有一个且仅有一个直接前驱。
- 除最后一个元素外,其他每一个元素有一个且仅有一个直接后继。
顺序表(sequence list)
定义
- 将线性表中的元素相继存放在一个连续的存储空间中
存储结构
- 数组
特点
- 线性表的顺序存储方式
存取方式
- 顺序存取
- 随机存取
插入
- 有n+1个位置可以插入数据,每个位置的数据移动次数为n-i,i=0…n
- 平均数据移动次数:1/(n+1) * n(n+1)/2 = n/2
删除
- 有n个数据可以删除,删除每个数据需要的移动次数为n-i-1,i=0…n-1
- 平均数据移动次数:1/n * n(n-1)/2 = (n-1)/2
应用
- 集合的并运算:在B中取一个元素,在A中查找,找不到就插入A中
- 集合的交运算:在B中取一个元素,在A中查找,未找到就在A中删除
链表(linked list)
概念
- 链表是线性表的链接存储表示。
- 是一种由节点组成,并能用于表示序列的数据结构。
单链表(single linked list)
- 用地址任意的存储单元存放线性表中的数据元素。
- 每个节点仅指向下一个节点,最后一个节点指向空(null)。
- 结构:数据域+指针域
- 存储结构:链式存储结构
- 特点:存储单元可以不连续
- 存取方式:顺序存取
- 基本运算:插入、删除、
- 插入:有三种情况,下图为不带表头节点的实现。
带表头节点实现均为第2,3中情况中的实现。
- 删除:不带表头与带表头的实现如下图所示。
- 建立单链表:
- 从空表开始,生成新节点
- 将读入数据存放到新结点的数据域中
- 将该新结点插入到链表的前端 / 后端
- 直到读入结束符为止
静态链表(static linked list)
- 用一维数组描述线性链表
循环链表(circular linked list)
- 每个节点指向下一个节点,最后一个节点指向第一个节点。
- 存储结构:链式存储结构
- 时间复杂度:
索引:O(n)
查找:O(n)
插入:O(1)
删除:O(1) - 可以解决的问题:约瑟夫问题、多项式(Polynomial)
- 约瑟夫问题:n 个人围成一个圆圈,首先第1个人从1开始一个人一个人顺时针报数, 报到第m个人,令其出列。然后再从下一个人开始,从1顺时针报数,报到第m个人,再令其出列,…,如此下去, 直到圆圈中只剩一个人为止。此人即为优胜者。
- 方法:双重循环控制,外层循环执行n-1次,是对n-1个人进行找人操作,内层循环执行m-1次,目的是数出m-1个人,然后删除第m个人。
- 多项式:n阶多项式有n+1项,系数a0,…,an,指数0,1, … ,n 升幂排列,进行多项式相加、相减
- 相加:扫描两个多项式,若都未检测完:
若当前被检测项指数相等,系数相加。若未变成 0,则将结果加到结果多项式。
若当前被检测项指数不等,将指数小者加到结果多项式。
若一个多项式已检测完,将另一个多项式剩余部分复制到结果多项式。
- 相加:扫描两个多项式,若都未检测完:
双向链表(doubly linked list)
- 每个节点有一个数据域和两个指针prior,next。prior指向前一个节点,next指向下一个节点;最后一个节点指向空。
- 插入操作:在p后插入q
q->prior = p;
q->next = p->next;
p->next = q;
q->next->prior = q; - 删除操作:删除p
p->next->prior = p->prior;
p->prior->next = p->next;
顺序表与链表的比较
- 基于空间的比较
- 存储分配的方式
(1)顺序表的存储空间是静态分配的
(2)链表的存储空间是动态分配的 - 存储密度 = 结点数据本身所占的存储量/结点结构所占的存储总量
(1)顺序表的存储密度 = 1
(2)链表的存储密度 < 1
- 存储分配的方式
- 基于时间的比较
- 存取方式
(1)顺序表可以随机存取,也可以顺序存取
(2)链表是顺序存取的 - 插入/删除时移动元素个数
(1)顺序表平均需要移动近一半元素
(2)链表不需要移动元素,只需要修改指针
- 存取方式