Ch14 数据结构与算法 · 闪卡 (Anki 导出)¶
100 张卡,涵盖 6 节核心。Anki Deck:
Ch14 数据结构与算法
Section A: 基础¶
Card 1¶
Front: 大 O 记号定义? Back: \(T(n) = O(f(n))\) 当 \(\exists c > 0, n_0: T(n) \leq c f(n), \forall n \geq n_0\)。
Card 2¶
Front: 主定理? Back: \(T(n) = a T(n/b) + f(n)\), 分三情况与 \(n^{\log_b a}\) 比较。
Card 3¶
Front: 递归三要素? Back: (1) 基例 (终止条件), (2) 递归调用 (规模缩小), (3) 返回组合。
Card 4¶
Front: 分治 vs 动态规划? Back: 分治: 子问题独立; DP: 子问题重叠, 用记忆化。
Card 5¶
Front: 平摊分析 (amortized)? Back: 单次操作平均成本。e.g., 动态数组扩容 \(O(1)\) 平摊。
Card 6¶
Front: 时间换空间经典例子? Back: 哈希表 (\(O(n)\) 空间换 \(O(1)\) 查找), DP 表 (\(O(n^2)\) 换 \(O(1)\) 查询)。
Card 7¶
Front: 空间换时间例子? Back: 记忆化递归 (memoization), 索引 (database)。
Card 8¶
Front: 尾递归优化? Back: 递归调用是函数最后操作, 编译器复用栈帧。Python 不支持。
Card 9¶
Front: 迭代 vs 递归? Back: 递归简洁, 但栈 \(O(n)\); 迭代空间 \(O(1)\) 但代码长。
Card 10¶
Front: 大 O 常见复杂度排序? Back: \(O(1) < O(\log n) < O(n) < O(n \log n) < O(n^2) < O(2^n) < O(n!)\)。
Section B: 数组与哈希¶
Card 11¶
Front: 数组随机访问复杂度? Back: \(O(1)\)。CPU 直接计算偏移。
Card 12¶
Front: 动态数组插入均摊? Back: 末尾插入 \(O(1)\) 平摊 (偶尔扩容 \(O(n)\)), 中间插入 \(O(n)\)。
Card 13¶
Front: 哈希表平均查找复杂度? Back: \(O(1)\)。最坏 \(O(n)\) (冲突)。
Card 14¶
Front: 哈希冲突解决方法? Back: (1) 链地址 (chaining), (2) 开放定址 (probing, e.g., 线性/二次/双重哈希)。
Card 15¶
Front: 装填因子? Back: \(\alpha = n/m\), \(n\) 元素数, \(m\) 桶数。> 0.7 通常扩容。
Card 16¶
Front: 一致性哈希? Back: 节点 / 数据映射到 0-2^32 环。增删节点只影响邻居, 用于分布式缓存。
Card 17¶
Front: 双指针算法适用场景? Back: 有序数组查找, 链表快慢指针, 字符串匹配。
Card 18¶
Front: 滑动窗口适用? Back: 数组 / 字符串子串问题, 求最长 / 最短满足条件子串。
Card 19¶
Front: 前缀和适用? Back: 区间求和 \(O(1)\) 查询, 多次询问。
Card 20¶
Front: Python list 是数组还是链表? Back: 动态数组 (C 实现), 不是链表。中间插入 \(O(n)\)。
Section C: 链表栈队¶
Card 21¶
Front: 链表 vs 数组核心差别? Back: 数组连续内存访问 \(O(1)\), 链表非连续访问 \(O(n)\); 数组插入 \(O(n)\), 链表 \(O(1)\)。
Card 22¶
Front: 单链表反转核心代码? Back:
prev, curr = None, head
while curr:
nxt = curr.next
curr.next = prev
prev = curr
curr = nxt
return prev
Card 23¶
Front: 快慢指针应用? Back: 链表环检测 (Floyd), 找中点, 找倒数第 k。
Card 24¶
Front: LRU Cache 实现? Back: 双向链表 + 哈希表。访问移到头, 淘汰尾。
Card 25¶
Front: 单调栈应用? Back: 下一个更大元素, 接雨水, 柱状图最大矩形。
Card 26¶
Front: 队列应用? Back: BFS, 任务调度, 滑动窗口, 消息队列 (Kafka)。
Card 27¶
Front: 优先队列底层?
Back: 二叉堆 (heap)。Python heapq 是最小堆。
Card 28¶
Front: 双端队列 (deque)?
Back: 两端插入删除 \(O(1)\)。Python collections.deque。
Card 29¶
Front: 循环队列? Back: 用数组 + head/tail 指针实现队列, 节省空间。
Card 30¶
Front: 表达式求值用栈还是队列? Back: 栈 (中缀 → 后缀 → 求值)。
Section D: 树¶
Card 31¶
Front: 二叉树前序遍历?
Back: 根 → 左 → 右。preorder(node): if node: print(node.val); preorder(node.left); preorder(node.right)。
Card 32¶
Front: 中序遍历 BST 结果? Back: 有序序列。
Card 33¶
Front: 层序遍历用什么数据结构? Back: 队列 (BFS)。
Card 34¶
Front: BST 查找复杂度? Back: 平均 \(O(\log n)\), 最坏 \(O(n)\) (退化成链表)。
Card 35¶
Front: AVL 树 vs 红黑树? Back: AVL 严格平衡 (高度差 ≤ 1), 查找快; 红黑树近似平衡 (黑高一致), 插入删除快。
Card 36¶
Front: 堆的插入复杂度? Back: \(O(\log n)\)。先放末尾, 上浮。
Card 33¶
Front: Heapify 一次建堆复杂度? Back: \(O(n)\)。从最后一个非叶节点下调。
Card 38¶
Front: Trie (前缀树) 应用? Back: 自动补全, 拼写检查, IP 路由。
Card 39¶
Front: 树状数组 (BIT) 用途? Back: 区间求和 / 更新 \(O(\log n)\)。比线段树简单。
Card 40¶
Front: 线段树用途? Back: 区间查询 / 更新 \(O(\log n)\), 支持多种聚合 (min/max/sum)。
Section E: 图¶
Card 41¶
Front: BFS 时间复杂度? Back: \(O(V + E)\)。队列实现。
Card 42¶
Front: DFS 时间复杂度? Back: \(O(V + E)\)。栈 / 递归实现。
Card 43¶
Front: Dijkstra 不适用什么图? Back: 有负权边的图。负权用 Bellman-Ford。
Card 44¶
Front: 拓扑排序前提? Back: DAG (有向无环图)。Kahn 算法或 DFS 后序逆序。
Card 45¶
Front: Bellman-Ford 复杂度? Back: \(O(VE)\)。可检测负权环。
Card 46¶
Front: Floyd-Warshall 复杂度? Back: \(O(V^3)\)。所有点对最短路。
Card 47¶
Front: Prim vs Kruskal? Back: Prim 适合稠密图 (\(O(V^2)\) 或 \(O(E \log V)\)), Kruskal 适合稀疏图 (\(O(E \log E)\), 用 Union-Find)。
Card 48¶
Front: Union-Find 优化? Back: 路径压缩 + 按秩合并 → 几乎 \(O(1)\)。
Card 49¶
Front: A 启发式函数要求? Back*: \(h(n) \leq \text{真实代价}\), 可采纳 (admissible)。否则不能保证最优。
Card 50¶
Front: 强连通分量 (SCC)? Back: 任意两节点互相可达的最大子图。Tarjan / Kosaraju 算法 \(O(V+E)\)。
Section F: 排序¶
Card 51¶
Front: 常见排序稳定性? Back: 稳定: 冒泡 / 插入 / 归并 / 计数 / Tim。不稳定: 选择 / 快排 / 堆排 / 希尔。
Card 52¶
Front: 快速排序最坏情况? Back: \(O(n^2)\) (每次选最大 / 最小为 pivot)。随机化 pivot 可避免。
Card 53¶
Front: 归并排序空间复杂度? Back: \(O(n)\)。需要辅助数组。
Card 54¶
Front: 堆排序空间? Back: \(O(1)\) 原地。
Card 55¶
Front: 计数排序适用? Back: 数据范围 \(k\) 较小, e.g., 0-100 的分数排序。\(O(n+k)\)。
Card 56¶
Front: 基数排序适用? Back: 定长整数 / 字符串。按位排序, \(O(nk)\)。
Card 57¶
Front: Tim 排序 (Python sort)? Back: 归并 + 插入, 自适应。识别已有有序片段 (run), 合并。最坏 \(O(n \log n)\)。
Card 58¶
Front: 二分查找前提? Back: 有序数组。
Card 59¶
Front: 二分查找边界 (左闭右闭)? Back:
lo, hi = 0, n - 1
while lo <= hi:
mid = (lo + hi) // 2
if arr[mid] == target: return mid
elif arr[mid] < target: lo = mid + 1
else: hi = mid - 1
return -1
Card 60¶
Front: 二分查找变种 (找左边界)? Back:
lo, hi = 0, n
while lo < hi:
mid = (lo + hi) // 2
if arr[mid] < target: lo = mid + 1
else: hi = mid
return lo
Section G: 现实应用¶
Card 61¶
Front: LLM 推理中 KV cache 用什么数据结构? Back: 哈希表 + 张量。vLLM PagedAttention 用 page table 类似 OS。
Card 62¶
Front: GNN 邻居采样用什么? Back: BFS (GraphSAINT), kNN (点云), 邻接表遍历。
Card 63¶
Front: 数据库索引底层? Back: B+ 树 (InnoDB), LSM 树 (LevelDB / RocksDB)。
Card 64¶
Front: 推荐系统 Top-K? Back: 堆 (heap), \(O(n \log k)\)。
Card 65¶
Front: PageRank 实现? Back: 邻接表 + 迭代幂法。GPU 上用 sparse mat-vec。
Card 66¶
Front: SLAM 路径规划? Back: Dijkstra / A* 在栅格图。
Card 67¶
Front: 编译器符号表? Back: 哈希表 (Python), 红黑树 (C++)。
Card 68¶
Front: Trie 在 LLM 应用? Back: BPE tokenizer 的 prefix cache, Beam search 缓存。
Card 69¶
Front: 数据库连接用什么算法? Back: Hash Join (等值), Sort-Merge Join (范围)。
Card 70¶
Front: 内存池用什么数据结构? Back: 双向链表 (空闲块), 哈希表 (按大小索引)。
Section H: 历史¶
Card 71¶
Front: Quick Sort 起源? Back: Tony Hoare, 1960。
Card 72¶
Front: Heap Sort 起源? Back: Williams / Floyd, 1964。
Card 73¶
Front: Dijkstra 起源? Back: Edsger Dijkstra, 1956 (设计), 1959 出版。
Card 74¶
Front: AVL 树起源? Back: Adelson-Velsky & Landis, 1962, 第一个自平衡树。
Card 75¶
Front: 红黑树起源? Back: Rudolf Bayer, 1972。
Card 76¶
Front: B+ 树起源? Back: Rudolf Bayer, 1972, 用于数据库索引。
Card 77¶
Front: Tarjan SCC 起源? Back: Robert Tarjan, 1972。
Card 78¶
Front: Tim 排序起源? Back: Tim Peters, 2002, Python 标准。
Card 79¶
Front: MapReduce 起源? Back: Google, Dean & Ghemawat, OSDI 2004。
Card 80¶
Front: PagedAttention 起源? Back: vLLM, Kwon et al., SOSP 2023。
Section I: 工程¶
Card 81¶
Front: Python list vs tuple? Back: list 可变, tuple 不可变 (哈希)。tuple 快 ~10%。
Card 82¶
Front: Python dict 实现? Back: 开放定址哈希表, 装填因子 2/3。Python 3.7+ 保插入序。
Card 83¶
Front: Python set 实现? Back: 同 dict, 但只存 key。
Card 84¶
Front: Python deque vs list? Back: deque 两端 \(O(1)\), list 末端 \(O(1)\), 头部 \(O(n)\)。
Card 85¶
Front: C++ STL vector 扩容策略? Back: 1.5× 或 2× 扩容。Java ArrayList 1.5×, Python list 1.125×。
Card 86¶
Front: Rust Vec 扩容? Back: 2× 扩容, \(O(1)\) 平摊。
Card 87¶
Front: C++ std::unordered_map vs std::map? Back: 前者哈希 \(O(1)\), 后者红黑 \(O(\log n)\), 后者有序。
Card 88¶
Front: 为什么 hash 函数要均匀? Back: 否则聚集 → 冲突 → 退化 \(O(n)\)。
Card 89¶
Front: 数据库 B+ 树为什么不用红黑? Back: B+ 树磁盘友好 (节点大, IO 少), 红黑树是内存结构。
Card 90¶
Front: LSM 树优势? Back: 写优化 (顺序 IO), 用于 KV 存储 (LevelDB, RocksDB)。
Section J: 跨章¶
Card 91¶
Front: Ch07 §04 Transformer 与 Ch14 §03 Trie 的关系? Back: BPE tokenizer 是 Trie 变种, 前缀匹配。
Card 92¶
Front: Ch12 §02 GNN 与 Ch14 §04 图算法的关系? Back: GNN 邻居采样 = BFS/DFS, GraphSAINT 用 Dijkstra/Union-Find。
Card 93¶
Front: Ch11 §05 SLAM 与 Ch14 §04 Dijkstra? Back: SLAM 回环检测用图, A* 用于路径规划。
Card 94¶
Front: Ch13 §03 虚拟内存与 Ch14 §02 LRU? Back: OS 页置换算法 = LRU 变种。
Card 95¶
Front: Ch05 §04 贝叶斯与 Ch14 §03 Trie? Back: 前缀概率 = Trie + 条件概率。
Card 96¶
Front: Ch08 §04 Diffusion 与 Ch14 §03 KD-Tree? Back: k-NN 去噪用 KD-Tree 找邻居。
Card 97¶
Front: Ch06 §04 RL 与 Ch14 §03 堆? Back: 优先级经验回放用堆 (PER)。
Card 98¶
Front: Ch03 §05 梯度与 Ch14 §05 排序? Back: 分布式 Shuffle 用排序。
Card 99¶
Front: Ch13 §04 并发与 Ch14 §03 优先队列? Back: 多线程任务调度用优先队列 (lock-free heap)。
Card 100¶
Front: 一句话总结 Ch14。 Back: 数据结构与算法 = AI 工程师内功。覆盖 §00 基础 (复杂度/递归) + §01 数组哈希 (\(O(1)\) 访问/查找) + §02 链表栈队 (LRU / 队列) + §03 树 (BST / 平衡 / Trie / 堆) + §04 图 (BFS / DFS / Dijkstra / MST) + §05 排序搜索 (快排 / 归并 / Tim / 二分)。是 GNN/SLAM/LLM 推理优化的基础。