目标
「我要学数据结构」这句话没法执行——它没有顺序、没有边界,也没有「怎么算学会了」。本 Lab 要把它改写成一份可检查、可迭代的个人学习地图:你知道先学什么、后学什么,每个主题做到哪一步算数,以及进度落后时先砍掉什么。
完成本 Lab 后,你应该能:
- 从一堆想学的东西里,挑出本学期真正要啃的 6~10 个主题,并说清谁依赖谁;
- 为其中任意一个主题,写出「解释、实现、测试、审阅」四类最小可交付产出;
- 拿这张图去和同伴互相挑毛病,而不是自己闷头改。
建议用时
30~45 分钟。第一次做会偏慢,因为难的不是画图,是把「想学」翻译成「做哪几件具体的事」。
前置知识
- 已经浏览过课程总目录,知道本课程分哪些章节、各章大概讲什么;
- 不需要会写代码——这份地图是「学习计划」,不是代码题。
参考成果:一份全课程学习地图
下面这份地图是完成本 Lab 的标准参考——覆盖本课程全部知识,是本学期的学习主线。它把 10 个主题按依赖关系分层,并标注了本月「必须做」与「以后再做」。
主题分层与依赖
依赖关系用箭头表示:A → B 意为「不先弄懂 A,B 就学不动」。
① 数据结构基础概念(地基)
├─→ ② 算法复杂度分析 ──→ ③ 内存视角与缓存局部性
│ ├─→ ⑨ 排序算法
│ └─→ ⑩ 算法思想
├─→ ④ 线性表 ──→ ⑤ 栈与队列
│ └─→ ⑧ 查找与索引
└─→ ⑥ 树与二叉树 ──→ ⑦ 图与遍历 ──→ ⑩ 算法思想
├─→ ⑧ 查找与索引
├─→ ⑨ 排序算法
└─→ ⑩ 算法思想依赖说明
| 主题 | 前置 | 为什么必须先于它 |
|---|---|---|
| ① 数据结构基础 | — | 一切术语的起点:逻辑结构、存储结构、ADT |
| ② 算法复杂度分析 | ① | 先有「操作」概念,才能数操作次数 |
| ③ 内存视角与缓存局部性 | ② | 要用 O 记号,且建立在「操作次数 × 单次代价」之上 |
| ④ 线性表 | ① | 逻辑/存储结构的具体化 |
| ⑤ 栈与队列 | ④ | 受限线性表 |
| ⑥ 树与二叉树 | ① | 另一种逻辑结构 |
| ⑦ 图与遍历 | ⑥ | DFS 依赖递归与树的先序遍历思想 |
| ⑧ 查找与索引 | ④⑥ | BST 依赖树,哈希依赖数组定位 |
| ⑨ 排序算法 | ②⑥ | 堆排序依赖堆,且要靠复杂度比较优劣 |
| ⑩ 算法思想 | ②⑥⑦⑨ | DP/回溯依赖树与递归,且要靠复杂度分析 |
- 本月「必须做」:① → ② → ③ → ④。这是后续所有章节的公共地基。
- 「以后再做」:⑦⑧⑨⑩ 的高级话题(如外部排序、最小生成树、网络流)。
四类最小产出(以「③ 内存视角与缓存局部性」为例)
解释(≤150 字):数据结构是内存的布局,算法是访问顺序。数组连续存储,遍历时缓存行一次搬 64 字节、命中率高;链表节点散落堆上,每次访问都可能缓存未命中。所以同为 O(n),数组遍历更快——大 O 只数操作次数,漏掉了「单次操作的代价」。
实现(最小代码):
// 同一 O(n),数组 vs 链表,代价不同
long long sum_array(int* a, int n) { // 连续访问,缓存友好
long long s = 0;
for (int i = 0; i < n; i++) s += a[i];
return s;
}
long long sum_list(Node* head) { // 跳跃访问,缓存不友好
long long s = 0;
for (Node* p = head; p; p = p->next) s += p->val;
return s;
}测试(≥3 个用例,含边界):
n = 10^6:两者结果相同,但数组明显更快;n = 10^7:数组对链表的倍数随规模增大而拉大;- 边界:链表节点按顺序分配(不打乱)时,两者速度趋同——验证「差异来自缓存布局,而非复杂度」。
审阅(一条具体 Review 意见):结论不能只停在「数组快、链表慢」,必须落到「操作次数 × 单次操作代价」——否则读者会误以为这是复杂度差异,而不是同一复杂度下的常数因子差异。
同伴反馈与修订
与同伴交换地图后,收到两条意见:
- 范围过大点:主题 ③「内存视角」一下子覆盖了 L1/L2/L3 缓存、缓存行、快排 vs 归并、B+ 树 vs 红黑树,一个学期消化不了。
- 遗漏点:「④ 线性表 → ⑤ 栈队列 → ⑥ 树 → ⑦ 图遍历」这条链上,缺了**「递归与调用栈」**这一环——后面图遍历的 DFS、DP 都要用它,却没有任何一个主题明确承载它。
修订说明(≤150 字):接受「遗漏点」,把「递归与调用栈」补进主题 ② 的四类产出里(复杂度分析本来就要分析递归深度与栈空间)。部分接受「范围过大点」:主题 ③ 收窄为「缓存行与连续/离散访问」,L1/L2/L3 分层只作背景一句话;B+ 树 vs 红黑树下移到主题 ⑧;保留「快排 vs 归并」,因为它是对比缓存局部性最直观的例子。
约束
- 主题必须来自本课程目录,不能自己另起一套;
- 依赖关系必须是有向的——画不出「谁必须先于谁」,说明这个主题要么太独立,要么你还没想清;
- 四类产出必须都是「可检查」的:写得出来、跑得起来、判得出对错、挑得出毛病。
验收标准
Review 提示
审阅者可检查:依赖图里有没有「环」(A 依赖 B、B 又依赖 A);四类产出里的「测试」是否真的能判对错(而不是「跑一遍没报错」);修订说明是否真的对应了同伴的某条具体意见,而不是一句空话。
思考
如果两周后进度落后,你会删减哪些非核心工作,同时保留怎样的最小学习闭环?