数据结构全书
总控图 复杂度表 演示 书目 笔记 发展史 产业 题库
Data Structures · 408 Field Guide

数据结构
全书精读

按考研 408 数据结构大纲编排。复杂度必须写清最好 / 平均 / 最坏与前提。可以少讲,不写错;数值例题已手算。

10 章 · 四大模块 手算 · KMP next / 哈夫曼 WPL / 探查 12 题 章末自测
01

绪论与复杂度

LEVEL 1

数据结构管的是数据对象、关系、操作。算法分析先钉死渐进记号,再谈哪一种输入。

1.1抽象与记号

抽象数据类型(ADT)规定数据对象、逻辑关系和基本操作,不规定顺序/链式等存储实现。大 O 描述上界,Ω 下界,Θ 同阶。平时说「O(n)」默认是渐进上界,不要把它写成精确步数。

1.2最好 / 平均 / 最坏

同一算法三条曲线可以不同。平均必须带分布前提:随机排列、随机插入、均匀散列等。「平均 O(log n)」若省略前提,在退化输入上是错的。

PITFALL · 不要只写一个 O()快排若只写 O(n log n),漏掉最坏 O(n²)。BST 若只写平均对数,漏掉 O(h) 与链状最坏。
CROSSREF总表见 复杂度速查。
02

线性表

LEVEL 2

线性表是同一类型元素的有限序列。实现分顺序与链式。关系约束是「相邻」,比树、图更紧。

2.1顺序表

随机访问下标 O(1)。在第 i 个位置插入或删除,平均要移动约一半元素,时间 O(n)。表尾操作才是 O(1)。

2.2单链表与前驱

按位查找、按值查找都是 O(n)。单链表按位定位 O(n);已定位到相关前驱结点后,插入/删除的改链操作 O(1)。只握着待删结点本身,单链表找不到前驱,不能 O(1) 删除(除非用后继覆盖再删后继这种特殊手法,题面要写明)。

双链表在已知结点上插入删除都可以 O(1) 改链。循环链表、头结点是实现细节,判空看头指针与头结点约定。

PITFALL · 「已知结点删除 O(1)」对单链表默认不成立。先问有没有前驱。
03

栈与队列

LEVEL 2

3.1栈

后进先出。共享栈把两个栈从数组两端往中间长,栈满当两顶相邻。括号匹配、表达式求值、递归消除、迷宫回溯是典型应用,不是四种新结构。

3.2循环队列

教材常用:front 指向队头元素,rear 指向下一个可插入位置。空:front == rear。满:(rear+1) mod M == front(浪费一个单元)。也可用计数或标志位区分空满,题面以约定为准。

PITFALL · 空满同形不浪费单元又不计长度时,空和满都会变成 front==rear。必须先约定用哪一种判满。
04

串

LEVEL 3

4.1朴素匹配

主串长 n、模式长 m。设 1≤m≤n。最坏比较次数 Θ((n−m+1)m),上界常简写 O(nm)。最好成功匹配情形:第一次对齐即匹配,比较 Θ(m)。

4.2KMP 与 next

失配时模式向右滑到「已匹配前缀」允许的位置,主串指针不回退。采用严蔚敏口径:1 下标,next[1]=0。

WORKED · P = abaabcj  1 2 3 4 5 6
P  a b a a b c
next 0 1 1 2 2 3
失配于 j 时改与 P[next[j]] 比。next[1]=0 表示模式整体右移一格、主串进一。

构造 next 本身是 O(m)。匹配 O(n)。不要把 nextval 优化和 next 混成一张表还不声明。

05

树与二叉树

LEVEL 3

5.1性质与遍历

约定根为第 1 层。二叉树第 i 层最多 2i−1 个结点;高 h 最多 2h−1。非空二叉树满足 n0 = n2 + 1。先序 / 中序 / 后序是三种遍历次序,不是三种树。层序用队列。

完全二叉树可用数组下标父子:1 下标时,若 2i≤n 则左孩子为 2i,若 2i+1≤n 则右孩子为 2i+1。满二叉树与完全二叉树不要混称。

5.2线索 · 并查集

线索二叉树用空指针穿到前驱后继,方便中序走访。并查集维护不相交集合:查找根、合并两棵树;路径压缩与按秩合并是实现优化。Kruskal 用它判回路。

06

查找树与哈夫曼

LEVEL 4

6.1BST / AVL

BST 查找 O(h)。随机插入形成的 BST,期望高度 O(log n);按有序序列插入会退化成链,最坏 O(n)。AVL 要求平衡因子 ∈ {−1,0,1},用单旋 / 双旋恢复,查找 O(log n)。红黑树只要求「近似平衡」的概念,408 不把旋转细则当必答题。

6.2B / B+ · 哈夫曼

m 阶 B 树:根若非叶至少 2 叉,非根内部结点至少 ⌈m/2⌉ 叉,所有叶在同一层(非空单结点 B 树的根可为叶)。B+ 树记录/数据只存叶,内部结点只存索引关键字,分隔关键字可在上层重复;叶常串成链表。二者都是多路平衡树,适合外存块访问——这里只写结构,不写操作系统页置换。

WORKED · HUFFMAN WPL · A7 B5 C2 D4先合 C+D=6,再合 B+6=11,再合 A+11=18。
深度:A=1,B=2,C=D=3。
WPL = 7×1 + 5×2 + 2×3 + 4×3 = 35。

哈夫曼树不唯一(并列权值时合并顺序可变),WPL 最小这一点不变。编码是前缀码。

07

图

LEVEL 4

7.1存储与遍历

邻接矩阵边查询 O(1),空间 Θ(V²)。邻接表适合稀疏图。邻接表上 BFS、DFS 都是 O(V+E)。BFS 用队列,得到无权图最短路;DFS 用栈 / 递归,不保证最短。

7.2最短路 · MST

Dijkstra:每次取未确定点中距离最小者做松弛,边权必须非负。矩阵实现常见 O(V²)。负权边不要套它。Floyd:三重循环 O(V³),允许负权,不允许负权环。Bellman-Ford 能检负环,但标准单源版本只能检出从源点可达的负权环;408 点到前提即可。

最小生成树:Prim 长树,Kruskal 按边权排序再并查集。无向连通带权图。两种算法得到的树可能不同,权值和相同(边权互异时树唯一)。

7.3拓扑 · 关键路径

拓扑排序只对有向无环图。关键路径在 AOE 网:事件最早 / 最迟发生时间,活动最早 / 最迟开始时间,松弛为 0 的活动在关键路径上。

PITFALL · Dijkstra 与负权哪怕只有一条负边,也不能保证正确。有负权先看题面允许哪个算法。
09

散列

LEVEL 3

散列函数把关键字映射到槽。除留余数法 h(k)=k mod p,p 常取不大于表长的素数。冲突不可避免。平均查找在均匀假设下接近 O(1);全部撞车时最坏 O(n)。

拉链:同槽做成链表。开放定址:线性探查 h+i,二次探查约定 h+i²,再散列。装载因子 α = n/m;同一散列/探查方式与均匀假设下,α 越大期望探查越长。开放定址还要求 α<1。删除常用墓碑标记,直接清空会截断探查链。

WORKED · m=11 · h(k)=k mod 11插入 19, 30, 41。
19→8。30→8 冲突,线性探查 → 9。41→8、9 已占 → 10。
二次探查:30→8+1²=9;41→8+2²=12≡1 (mod 11)。
CROSSREF散列演示
10

排序

LEVEL 4

10.1八大内排

算法最好平均最坏空间稳定
直接插入O(n)O(n²)O(n²)O(1)是
折半插入O(n log n) 比较移动仍 Θ(n²)同左O(1)是
希尔与增量有关与增量有关可达 O(n²)O(1)否
冒泡O(n)O(n²)O(n²)O(1)是
快速O(n log n)O(n log n)O(n²)平均 O(log n)否*
简单选择O(n²)O(n²)O(n²)O(1)否*
堆O(n log n)O(n log n)O(n log n)O(1)否*
归并O(n log n)O(n log n)O(n log n)O(n)是
基数O(d(n+r))同左同左O(n+r)是†

* 教材默认实现通常不稳定;「可以改成稳定」不当作默认结论。† 每一位必须用稳定的桶/计数排序。建堆是 O(n),不是 O(n log n)。快排最坏出现在每次枢轴极偏(如已序且取端点)。

10.2外排概念

数据在外存。先生成初始归并段,再多路归并。败者树减少比较次数。这里只要求概念,不编造某次 I/O 次数。

QZ

章末自测

LEVEL 3