本章要回答的三个问题:为什么"按下标取元素"在数组里是一步直达、在链表里却要一步步走?栈和队列只是"受限的线性表",凭什么值一个专章?哈希表号称一步命中,它的代价和翻车条件是什么?
线性结构是所有结构的原材料:字符串是字符数组、哈希桶挂的是链表、树的节点间靠"指针链"相连、图的邻接表本质是链表的集合。它们回答同一个母题——元素排成一条线时,不同的"接线方式"让哪些操作一步到位、哪些操作寸步难行。
数组和链表是这条线的两种极端接法:连续内存对随机访问,离散节点对插删。栈与队列在这条线上加了访问规则(只许一头进出),换来了"顺序即语义"的简洁,函数调用栈、撤销栈、消息队列全靠它。哈希表则干脆跳出"相邻关系",用哈希函数直接算出元素的住址,把查找的价格打到常数——代价藏在冲突与扩容里。五种结构吃透,后面树、图、排序的每一步推理都有落点。
这五种结构也是面试与工程选型的高频考点,但背结论没有用:数组的均摊扩容、链表的反转、哈希的退化条件,每一个都要能边画图边推演,才算真正入手。本册的讲法因此一律"先给现场、再给结论"——每个复杂度数字都有可复算的实验垫底。
对照开头的问题,本章的知识点清单如下,全部可动手验证:
| 节 | 回答哪个问题 | 关键产出 |
|---|---|---|
| 2.1 数组 | 连续内存买了什么、卖了什么 | 内存布局图、搬移计数、动态数组均摊复算 |
| 2.2 链表 | 指针接线换来什么 | 三种链表变体、反转与快慢指针、与数组对比表 |
| 2.3 栈 | 只许一头进出为什么值钱 | 括号匹配、调用栈模型、栈帧图 |
| 2.4 队列 | 先来先服务的实现内幕 | 环形队列取模法、判满条件、双端队列 |
| 2.5 哈希表 | 一步命中的代价 | 冲突处理模拟、装载因子与扩容、最坏退化 |
本章出口是三件兵器:随机访问(数组)、顺序访问(链表及其衍生)、关键字定位(哈希表)。第三章的树是"链表的多叉推广"——每个节点不止一个后继;堆与优先队列(第三章)建立在数组的父子下标映射上;第四章图的邻接表是链表数组;第五章排序的主战场就是数组。线性心法不牢,后面每章都要回头补课。自检方法也很简单:合上书,把五种结构各画一张内存示意图,标出每个操作的代价来源——画不出的那种,就是该重读的节。