Chap3 列表
返回:0300 数据结构总目录 · 上一章:0302 Chap2 向量 · 下一章:0304 Chap4 栈与队列
1、学习目标
列表是线性结构的链式实现。它牺牲按秩随机访问,换来局部插入、删除时不需要整体搬移元素。复盘时要反复比较:向量适合按秩访问,列表适合频繁插入删除和稳定节点位置。
| 模块 | 要掌握的内容 |
|---|---|
| 节点 | 前驱、后继、数据域 |
| 哨兵 | header、trailer 简化边界 |
| ADT | 插入、删除、查找、去重、遍历 |
| 无序列表 | 顺序查找、去重 |
| 有序列表 | 有序查找、唯一化 |
| 排序 | 选择排序、插入排序、归并排序 |
2、资料范围
| PDF 课件 | 内容 |
|---|---|
03.List.A.interface_Implementation.pdf |
列表接口与实现 |
03.List.B.Unsorted_list.pdf |
无序列表 |
03.List.C.Sorted_list.pdf |
有序列表 |
03.List.D.Selectionsort.pdf |
选择排序 |
03.List.E.Insertionsort.pdf |
插入排序 |
03.List.F.Mergesort.pdf |
归并排序 |
03.List.X1-X3 |
游标、Java 序列、Python List |
3、节点与列表结构
典型双向链表节点:
1 | template <typename T> |
列表通常使用两个哨兵:
1 | header <-> first <-> ... <-> last <-> trailer |
哨兵的价值是统一边界情况:
- 空表时
header->succ == trailer。 - 首元素也有前驱,末元素也有后继。
- 插入删除时不用单独判断头尾。
4、插入与删除
在节点 p 前插入:
1 | ListNode<T>* insertBefore(ListNode<T>* p, const T& e) { |
删除节点:
1 | T remove(ListNode<T>* p) { |
如果已经定位到节点,插入和删除都是 O(1)。但“定位”通常需要从头或尾扫描,所以整体操作不一定是常数时间。
5、无序列表
无序列表查找只能线性扫描:
1 | ListNode<T>* find(const T& e, int n, ListNode<T>* p) const { |
去重思路:
1 | int deduplicate() { |
复杂度 O(n^2)。
6、有序列表
有序列表中相同元素相邻,可以线性唯一化:
1 | int uniquify() { |
复杂度 O(n)。
7、列表排序
7.1 选择排序
选择排序适合列表的原因:找到最大元素后,把它移动到有序区前端,只改指针或节点数据即可。
过程:
1 | 在未排序区间中找最大节点,将其放到后端有序区间前面。 |
复杂度 O(n^2),不稳定。
7.2 插入排序
插入排序适合接近有序的数据:
1 | 从前往后扫描,将当前元素插入到前面已排序区间的合适位置。 |
复杂度:
| 情况 | 复杂度 |
|---|---|
| 最好 | O(n) |
| 最坏 | O(n^2) |
| 稳定性 | 稳定 |
7.3 归并排序
链表归并排序不需要像向量那样大量移动元素,合并时可以通过改指针连接节点。
1 | 拆成两半 -> 分别排序 -> 合并两个有序链表 |
复杂度 O(n log n),稳定。
8、向量与列表对比
| 操作 | 向量 | 列表 |
|---|---|---|
| 按秩访问 | O(1) |
O(n) |
| 已定位插入 | O(n) |
O(1) |
| 已定位删除 | O(n) |
O(1) |
| 查找 | O(n) |
O(n) |
| 缓存友好 | 好 | 较差 |
| 空间额外开销 | 容量冗余 | 前驱/后继指针 |
不要简单说“链表插入删除更快”。准确说法是:如果已经拿到节点位置,列表插入删除是常数时间;如果还要查找位置,仍然可能是线性时间。
9、易错点
| 易错点 | 修正 |
|---|---|
| 删除节点后继续访问它 | 删除前先保存后继 |
| 忘记维护双向指针 | 前驱的后继、后继的前驱都要改 |
| 不用哨兵导致边界代码复杂 | 用 header/trailer 统一空表、头尾插入删除 |
| 把列表当数组用 | 列表不适合频繁按秩随机访问 |
10、复盘清单
| 检查项 | 状态 |
|---|---|
| 能画出带哨兵的双向链表 | 待复盘 |
能写出 insertBefore/remove 指针修改顺序 |
待复盘 |
| 能解释列表插入删除的真实复杂度 | 待复盘 |
| 能比较无序去重和有序唯一化 | 待复盘 |
| 能说明选择排序、插入排序、归并排序在列表上的特点 | 待复盘 |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Ruiqy~!







