数据结构 · 2027 考研计算机 408

第 1 章 绪论(基本概念与算法分析)

目标院校:四川大学 / 电子科技大学 | 建议用时:概念 2 小时 + 例题练习 3 小时

本章地位:绪论是 408 数据结构的「语法说明书」,直接考分不多(选择题 0~2 分),但时间 / 空间复杂度分析是全卷暗线——后面每一章的算法题都要用大 O 说理由。真题最爱考两类:① 逻辑结构与存储结构的辨析(概念题);② 给一段 C 代码分析时间复杂度(频次法)。本章把这两件事一次讲透,所有复杂度结论都配「逐代具体数值验证」。

1.1 基本概念与逻辑结构

定义数据是信息的载体;数据元素是数据的基本单位;数据项是构成数据元素的不可分割的最小单位。数据结构是相互之间存在一种或多种特定关系的数据元素的集合,形式地记为二元组 \[ \mathrm{DS}=(D,\ S) \] 其中 \(D\) 是数据元素的有限集,\(S\) 是 \(D\) 上关系的有限集。
一句话记忆数据项组成数据元素(如一个学生的「学号」数据项组成一条学生记录),数据元素的集合 + 元素间关系 = 数据结构。三要素:逻辑结构、存储结构(物理结构)、数据的运算。

1.1.1 逻辑结构:与实现无关的「关系图」

分类按元素间的关系,逻辑结构分为四类:
  1. 集合:元素间除「同属一个集合」外无其他关系;
  2. 线性结构:一对一前驱后继(线性表、栈、队列、串);
  3. 树形结构:一对多(双亲与孩子);
  4. 图状结构(网状):多对多。
后三类又统称非线性结构。
集合 仅「同属一个集合」 a₁ a₂ a₃ 线性结构 一对一(前驱 / 后继) 树形结构 一对多 图状结构 多对多
图 1-1 逻辑结构四分类:集合(无关系)· 线性(1:1)· 树形(1:n)· 图状(n:n,后三类统称非线性结构)

1.1.2 存储结构:落进内存的「实现方式」

四种存储结构
  1. 顺序存储:相邻元素存放在地址连续的存储单元里(逻辑相邻 ⇒ 物理相邻);
  2. 链式存储:用指针指示逻辑关系,物理位置可不相邻;
  3. 索引存储:附加索引表(关键字 → 地址)加速查找;
  4. 散列(哈希)存储:按关键字直接计算存储地址。
① 顺序存储(数组) 0 1 2 3 4 a₁ a₂ a₃ a₄ a₅ 2000 2004 2008 2012 2016 地址连续,按位置随机存取: addr(aᵢ) = 2000 + 4i 逻辑相邻 ⇒ 物理相邻 ② 链式存储(指针) head a₁ a₂ a₃ a₄ ∧ 存储单元可不相邻,「相邻」关系由指针(红)表达
图 1-2 同一个线性表 a₁…a₅ 的两种存储实现:顺序存储靠连续地址,链式存储靠指针
易错① 逻辑结构与存储结构是两个独立维度:同一逻辑结构(如表)可用顺序或链式实现;判断题中「循环队列」「哈希表」「顺序表」都是存储结构 / 存储实现层面的名词,而「队列」「栈」「线性表」才是逻辑结构;
② 「有序表」指元素按关键字有序的线性表,仍属逻辑结构范畴(是线性表的特例),不要因「顺序」二字误判为存储结构;
③ 数据的运算:定义依赖于逻辑结构,实现依赖于存储结构——两句话方向别背反。
例 1 高频考点 逻辑结构与存储结构辨析

下列关于数据结构的叙述中,正确的是( )
A. 循环队列是一种逻辑结构 B. 哈希表是一种逻辑结构 C. 数据的逻辑结构独立于其存储结构 D. 数据运算的定义依赖于数据的存储结构

查看解答

C。逐项分析:

A 错:循环队列是「队列 + 顺序存储 + 取模绕回」的实现方案,属存储结构层面;队列本身才是逻辑结构。

B 错:哈希(散列)是第四种存储结构,哈希表是散列存储的产物。

C 对:逻辑结构描述元素间的关系,与怎样存进内存无关;这正是「一个队列可以分别用数组或链表实现」的原因。

D 错:说反了——运算的定义基于逻辑结构(如栈只说「先进后出」),实现才依赖存储结构。

练习 1

数据结构的三要素是什么?并各举一例。

查看答案

三要素:逻辑结构(如二叉树的「一对多」关系)、存储结构(如用数组带下标 2i、2i+1 存完全二叉树)、数据的运算(如入栈、出栈的定义与实现)。

练习 2 易错

判断下列说法的正误:(1) 有序表是一种存储结构;(2) 栈、队列、串都是线性结构;(3) 顺序存储要求逻辑相邻的元素物理上也相邻。

查看答案

(1) 错:有序表是「元素按关键字有序的线性表」,属逻辑结构;顺序表才是存储结构。

(2) 对:三者元素都是一对一的线性关系(栈、队列只是运算受限的线性表)。

(3) 对:这正是顺序存储的定义;链式存储则无此要求(用指针表达逻辑相邻)。

1.2 算法与时间复杂度 高频考点

算法及其五个特性算法是对特定问题求解步骤的一种描述。它必须满足:
  1. 有穷性:有限步之后必然终止(程序可以不满足——如操作系统在无限循环中运行,程序 ≠ 算法);
  2. 确定性:每条指令含义明确、无二义;
  3. 可行性:每步都可通过已实现的基本运算完成;
  4. 输入:零个或多个;
  5. 输出:一个或多个(至少一个,注意「零个输出」是错的)。
设计目标:正确性、可读性、健壮性(对非法输入能处理而非崩溃)、高效率与低存储量。

1.2.1 大 O 记号与推导规则

定义若存在正常数 \(c\) 与 \(n_0\),使得对一切 \(n\ge n_0\) 有 \[ T(n)\le c\cdot f(n) \] 则记 \(T(n)=O(f(n))\),称 \(f(n)\) 为 \(T(n)\) 的渐进上界。大 O 抓「增长趋势」,忽略常数与低阶项。
三条推导规则① 加法规则:\(T_1+T_2=O(\max(f_1,f_2))\)(顺序执行的程序段取最慢者);
② 乘法规则:\(T_1\times T_2=O(f_1\cdot f_2)\)(嵌套执行相乘);
③ 常数因子与低阶项直接丢弃。常用阶从小到大: \[ O(1)\lt O(\log_2 n)\lt O(n)\lt O(n\log_2 n)\lt O(n^{2})\lt O(n^{3})\lt O(2^{n})\lt O(n!) \]
n T(n) n² n log₂n n log₂n
图 1-3 各阶增长速度示意(未按真实比例):\(n^{2}\) 爆炸式增长、对数阶最平缓——优化一个「阶」远胜过优化常数倍(呼应自测 6/7:同 1 秒,\(n^{2}\) 只能跑约 \(3\times10^{4}\) 条数据,\(n\log_2 n\) 可跑约 \(4\times10^{7}\))
易错① 不加说明时,时间复杂度指最坏情况下的渐进阶(平均、最好情况题目会明说);
② 大 O 中对数底数理论上无关(只差常数因子),但 408 习惯写 \(O(\log_2 n)\);
③ 分析对象是基本操作的频次(深层循环体的执行次数),不是「代码行数」;外层循环变量判断要比执行体多一次(退出时的失败判断),频次统计要数准。

1.2.2 五类典型循环逐一验证

例 2 双重循环(频次统计法)

// 分析下列程序段的时间复杂度

int sum = 0;                        // ①
for (int i = 1; i <= n; i++)        // ②
    for (int j = 1; j <= n; j++)    // ③
        sum++;                       // ④
查看解答

逐条统计频次:

① 执行 1 次;② 外层变量 \(i\) 从 1 递增到 \(n\),加上退出时那次失败判断,共判断 \(n+1\) 次;③ 外层每轮中 \(j\) 都从 1 判断到 \(n+1\)(含失败),共 \(n(n+1)\) 次;④ 最内层体执行 \(n^{2}\) 次。

\[ T(n)=n^{2}+n(n+1)+(n+1)+2=2n^{2}+2n+3=O(n^{2}) \]

取最高阶项即可。频次法口诀:「外层判 \(n+1\),内层套乘再判多一次,只留最高阶」。

例 3 高频考点 倍增循环(对数阶)

// n > 1

int i = 1;
while (i <= n)
    i = i * 2;
查看解答

\(i\) 的取值序列:\(1,2,4,\dots,2^{t}\)。设循环体执行了 \(t+1\) 次后 \(i=2^{t+1}\gt n\) 终止,则 \(2^{t}\le n\lt 2^{t+1}\),即 \(t=\lfloor\log_2 n\rfloor\),循环体共执行 \(\lfloor\log_2 n\rfloor+1\) 次:

\[ T(n)=O(\log_2 n) \]

数值验证(\(n=8\)):\(i=1\to2\to4\to8\),四次判断通过、循环体执行 4 次,第 5 次判断 \(16\gt 8\) 退出。\(\lfloor\log_2 8\rfloor+1=4\) ✓。又 \(n=10\):\(i=1,2,4,8\) 共 4 次,\(\lfloor\log_2 10\rfloor+1=3+1=4\) ✓。

n = 8 1 2 4 8 16 ×2 ×2 ×2 16 > n:判断失败,退出 循环体执行 4 次 = ⌊log₂8⌋ + 1
图 1-4 倍增循环的 i 取值序列(\(n=8\)):每轮 ×2,只走对数步就追上 n

套路总结:变量每轮乘常数(或除常数)⇒ 对数阶;每轮加减常数 ⇒ 线性阶。

例 4 依赖型双重循环(求和法)
int sum = 0;
for (int i = 1; i <= n; i++)
    for (int j = 1; j <= i; j++)
        sum++;
查看解答

内层次数依赖外层变量:第 \(i\) 轮内层执行 \(i\) 次,总计

\[ \sum_{i=1}^{n}i=\frac{n(n+1)}{2}=\frac{n^{2}}{2}+\frac{n}{2}=O(n^{2}) \]

数值验证(\(n=4\)):内层次数 \(1+2+3+4=10=\frac{4\times5}{2}\) ✓。

i=1 i=2 i=3 i=4 1 个 2 个 3 个 4 个 Σi = 1+2+3+4 = 10 = 4×(4+1)/2
图 1-5 内层次数依赖外层(\(n=4\)):上三角共 10 个点,恰为 \(4\times4\) 方阵的一半 → \(O(n^{2})\)

易错:内层上界是 \(i\) 不是 \(n\),不能直接写 \(n\times n\);先求和再取阶。

例 5 真题风格 线性 × 对数混合
int sum = 0;
for (int i = 1; i <= n; i++)
    for (int j = 1; j <= n; j = j * 2)
        sum++;
查看解答

外层 \(n\) 轮;每轮内层是例 3 型倍增循环,执行 \(\lfloor\log_2 n\rfloor+1\) 次。由乘法规则:

\[ T(n)=n\cdot\big(\lfloor\log_2 n\rfloor+1\big)=O(n\log_2 n) \]

数值验证(\(n=8\)):外层 8 轮 × 内层 4 次 = 32 次,\(8\times(\lfloor\log_2 8\rfloor+1)=8\times4=32\) ✓。

例 6 易错 递归的复杂度(递归树估计)
long fib(int n) {
    if (n <= 1) return n;          // 基例
    return fib(n - 1) + fib(n - 2); // 两次递归调用
}
查看解答

每个非基例节点分裂出 2 个子调用,递归树第 \(k\) 层最多 \(2^{k}\) 个节点,深度约 \(n\),调用总次数的量级为

\[ T(n)=O(2^{n}) \]

(精确说树中节点数与斐波那契数本身同阶,约 \(O(1.618^{n})\),408 标准答案记 \(O(2^{n})\)。)

套路总结:单分支递归(如 \(f(n)=f(n-1)+O(1)\))画「链」→ 线性;多分支递归画「树」→ 指数。递归算法的空间复杂度还要算递归工作栈(见 1.3)。

练习 3

分析下列程序段的时间复杂度:

int x = 2;
while (x < n / 2)
    x = 2 * x;
查看答案

每轮 \(x\) 翻倍,第 \(k\) 轮后 \(x=2^{k+1}\),终止条件 \(2^{k+1}\ge n/2\),即 \(k\ge\log_2(n/4)\):

\[ T(n)=O(\log_2 n) \]

(这是 2011 年真题原型的「除以 2」变式:循环变量指数增长,判断右端是常数倍 \(n\),不改变对数阶。)

练习 4

分析下列程序段的时间复杂度:

int i = 1;
while (i * i * i <= n)
    i++;
查看答案

循环体执行次数 \(t\) 满足 \(t^{3}\le n\lt(t+1)^{3}\),即 \(t=\lfloor\sqrt[3]{n}\rfloor\):

\[ T(n)=O(\sqrt[3]{n})=O(n^{1/3}) \]

数值验证(\(n=27\)):\(i=1,2,3\) 时判断通过(\(27\le27\) ✓),\(i=4\) 时 \(64\gt27\) 退出,循环体恰执行 \(3=\lfloor\sqrt[3]{27}\rfloor\) 次 ✓。

练习 5 方法

求 \(n\) 的阶乘的递归算法(\(f(0)=1\),\(f(n)=n\times f(n-1)\))的时间复杂度。

查看答案

单分支递归,递归深度为 \(n\)(\(f(n)\to f(n-1)\to\cdots\to f(0)\)),每层做一次乘法:

\[ T(n)=O(n) \]

自检:\(f(4)\) 的调用链为 \(f(4)\to f(3)\to f(2)\to f(1)\to f(0)\),共 5 次调用 = \(n+1\) 次 ✓。

1.3 空间复杂度

定义算法的空间复杂度 \(S(n)\) 是算法所需辅助存储空间关于问题规模 \(n\) 的渐进量级(不含输入数据本身占用的空间)。若辅助空间是常数个变量,称算法原地工作,\(S(n)=O(1)\)。
易错① 递归算法的空间复杂度必须计入递归工作栈:每层调用占一帧,深度多少层就 \(O(\text{深度})\);
② 时间换空间、空间换时间是常见权衡(见例 7);两者都最优通常做不到,按题意取舍。
例 7 方法 逆置数组的两种实现(时空权衡)

// 将 a[0..n-1] 原地逆置?两种实现对比

void reverse1(int a[], int n) {          // 实现一:辅助数组
    int b[MAX];
    for (int i = 0; i < n; i++)
        b[n - 1 - i] = a[i];             // 倒着抄一遍
    for (int i = 0; i < n; i++)
        a[i] = b[i];                     // 再抄回来
}                                        // T=O(n), S=O(n)

void reverse2(int a[], int n) {          // 实现二:对折交换(原地)
    for (int i = 0; i < n / 2; i++) {
        int t = a[i];
        a[i] = a[n - 1 - i];
        a[n - 1 - i] = t;
    }
}                                        // T=O(n), S=O(1)
查看解答

两者时间都是 \(O(n)\)(都把每个元素碰常数次);空间上实现一开了长度 \(n\) 的辅助数组 \(b\),\(S(n)=O(n)\);实现二只用临时变量 \(t\),原地工作,\(S(n)=O(1)\)。

数值验证(\(n=5\),下标 0~4):对折交换执行 \(i=0,1\) 两轮,交换 \((0,4)\)、\((1,3)\),中间 \(a[2]\) 不动——\(\lfloor 5/2\rfloor=2\) 轮,结果正确 ✓。

套路总结:「对折 / 双指针」是原地操作的标志动作;题目限内存(如嵌入式场景)优先实现二。

例 8 递归的空间复杂度(递归工作栈)

求 1.2 节例 5 的阶乘递归与例 6 的 fib 递归各自的空间复杂度。

查看解答

阶乘递归:调用链 \(f(n)\to f(n-1)\to\cdots\to f(0)\),栈深 \(n+1\) 帧:

\[ S(n)=O(n) \]

fib 递归:虽然调用次数是 \(O(2^{n})\),但栈是「一条当前路径」——任意时刻活跃的调用只构成从根到某叶的一条路径,最大深度约 \(n\):

\[ S(n)=O(n)\quad(\text{不是 }O(2^{n})!) \]

易错:调用次数 ≠ 栈深度。递归树再宽,同时挂起的活动帧只等于当前递归路径长度。

练习 6 易错

判断:(1) 算法的时间复杂度与所用的计算机、编程语言有关;(2) 若算法的每层递归调用占用常数空间且递归深度为 \(\log_2 n\),则 \(S(n)=O(\log_2 n)\)。

查看答案

(1) 错。大 O 描述渐进增长趋势,与机器速度、语言编译产物无关(那影响的是常数因子);运行「时长」与机器有关,但「阶」无关。

(2) 对。栈深 \(\log_2 n\)、每帧常数空间,\(S(n)=O(\log_2 n)\)——这正是后面二分查找递归版的空间开销。

1.4 章末自测 真题风格

限时 45 分钟,先做后看答案。难度:★★ 基础 / ★★★ 强化 / ★★★★ 冲刺。所有复杂度结论自检:代入两三个具体的 \(n\) 数值验证次数。

自测 1(选择 · ★★)

算法和程序的区别之一在于算法必须具备( )
A. 每条指令的确定性 B. 可行性 C. 有穷性 D. 至少一个输入

查看答案

C。程序(如操作系统)可以在无限循环中永不终止,算法必须在有限步内结束——有穷性是「算法 ≠ 程序」的关键区别;A、B 算法程序都要满足,D 错在输入可以是零个(输出必须至少一个)。

自测 2(选择 · ★★★)

下列复杂度按增长速度从小到大排列正确的是( )
A. \(O(\log_2 n)\lt O(\sqrt n)\lt O(n\log_2 n)\lt O(n^{3/2})\) B. \(O(\sqrt n)\lt O(\log_2 n)\lt O(n^{3/2})\lt O(n\log_2 n)\) C. \(O(\log_2 n)\lt O(n\log_2 n)\lt O(\sqrt n)\lt O(n^{3/2})\) D. \(O(n\log_2 n)\lt O(\log_2 n)\lt O(\sqrt n)\lt O(n^{3/2})\)

查看答案

A。对数慢于任何正幂次:\(\log_2 n\lt n^{\varepsilon}\);幂次间比较指数:\(\sqrt n=n^{1/2}\lt n^{1.5}\);而 \(n\log_2 n\) 夹在 \(n^{1}\) 与 \(n^{1+\varepsilon}\) 之间。验证 \(n=1024\):\(\log_2 n=10\)、\(\sqrt n=32\)、\(n\log_2 n=10240\)、\(n^{3/2}=32768\),大小关系吻合 ✓。

自测 3(选择 · ★★★ 高频考点)

下列程序段的时间复杂度为( )

int count = 0;
for (int i = 1; i <= n; i++)
    for (int j = 2 * i; j <= n; j++)
        count++;

A. \(O(\log_2 n)\) B. \(O(n)\) C. \(O(n\log_2 n)\) D. \(O(n^{2})\)

查看答案

D。第 \(i\) 轮内层执行 \(\max(n-2i+1,\,0)\) 次,只有 \(i\le n/2\) 时有贡献:

\[ \sum_{i=1}^{\lfloor n/2\rfloor}(n-2i+1)\approx\frac{n}{2}\cdot n-2\cdot\frac{(n/2)^{2}}{2}=\frac{n^{2}}{4}=O(n^{2}) \]

数值验证(\(n=4\)):\(i=1\) 内层 \(j=2,3,4\) 共 3 次;\(i=2\) 内层 \(j=4\) 共 1 次;\(i=3,4\) 内层 0 次;合计 4 次 \(=n^{2}/4\) ✓。

自测 4(选择 · ★★)

下列程序段的时间复杂度为( )

int i = 1;
while (i * i <= n)
    i = i + 2;

A. \(O(\log_2 n)\) B. \(O(\sqrt n)\) C. \(O(n)\) D. \(O(n\log_2 n)\)

查看答案

B。\(i\) 每轮加 2 是线性增长,循环体次数 \(t\) 满足 \(t^{2}\lesssim n\),\(t=O(\sqrt n)\)(增量 2 只差常数因子)。验证 \(n=16\):\(i=1,3,5\) 判断通过(\(25\gt16\) 时停),执行 3 次 \(\approx\sqrt{16}/2\) ✓。

自测 5(选择 · ★★)

二叉树、队列、无向图的逻辑结构分别属于( )
A. 树形、线性、图状 B. 树形、线性、集合 C. 非线性、非线性、图状 D. 树形、非线性、图状

查看答案

A。队列是一对一的线性结构(运算受限的线性表),不要因「受限」误归为非线性;二叉树一对多,无向图多对多。

自测 6(填空 · ★★★)

某计算机执行基本操作的速度约为 \(10^{9}\) 次 / 秒。一个 \(O(n^{2})\) 的算法要在 1 秒内完成,\(n\) 最大约为 \(\underline{\hspace{1.5cm}}\)。

查看答案

需 \(n^{2}\le 10^{9}\),即 \(n\le\sqrt{10^{9}}\approx31623\)。精确核对边界:\(31622^{2}=999\,950\,884\le10^{9}\),而 \(31623^{2}=1\,000\,014\,129\gt10^{9}\),故最大 \(n=31622\)(按数量级答「约 \(3\times10^{4}\)」也对)。

自测 7(填空 · ★★★)

同一计算机上,\(O(n\log_2 n)\) 的算法 1 秒内可处理的数据规模约为 \(\underline{\hspace{1.5cm}}\)(数量级)。

查看答案

需 \(n\log_2 n\le10^{9}\)。试 \(n=4\times10^{7}\):\(\log_2(4\times10^{7})=2+\log_2 10^{7}\approx2+23.25=25.25\),乘积 \(\approx1.01\times10^{9}\),恰在边界附近。故约 \(4\times10^{7}\)(\(10^{7}\) 数量级)——可见把 \(O(n^{2})\) 优化成 \(O(n\log_2 n)\),可处理规模从 \(3\times10^{4}\) 提升到 \(4\times10^{7}\),提升千倍以上。

自测 8(填空 · ★★)

递归算法 \(\text{sum}(n)=\text{sum}(n-1)+n\)(\(\text{sum}(0)=0\))的时间复杂度为 \(\underline{\hspace{1cm}}\),空间复杂度为 \(\underline{\hspace{1cm}}\)。

查看答案

时间:递归深度 \(n\)、每层 \(O(1)\),\(T(n)=O(n)\);空间:递归工作栈深 \(n+1\) 帧,\(S(n)=O(n)\)。

自测 9(解答 · ★★★)

写出下列程序段中语句 ①②③④ 的频次(用 \(n\) 表示),并给出总的时间复杂度。

int s = 0;                          // ①
for (int i = 1; i <= n; i++) {      // ②
    for (int j = 1; j < n; j++)     // ③
        s = s + a[i][j];            // ④
}
查看解答

① 执行 \(1\) 次;② 外层判断 \(n+1\) 次(含退出时一次失败);③ 外层每轮中 \(j\) 从 1 判断到 \(n\)(\(j\lt n\),故 \(j=n\) 那次失败),共 \(n\) 次判断 → 总计 \(n\cdot n=n^{2}\) 次;④ 执行 \((n-1)\) 次每轮 → 总计 \(n(n-1)\) 次。

\[ T(n)=1+(n+1)+n^{2}+n(n-1)=2n^{2}+n+2=O(n^{2}) \]

数值验证(\(n=3\)):③ 每轮判断 3 次 × 3 轮 = 9 = \(n^{2}\) ✓;④ 每轮 2 次 × 3 轮 = 6 = \(n(n-1)\) ✓。

易错:内层条件是 \(j\lt n\)(不带等号),每轮判断次数是 \(n\) 不是 \(n+1\)——频次题先看清循环边界开闭。

自测 10(解答 · ★★★★ 冲刺)

分析下列递归程序的时间复杂度与空间复杂度。

void f(int n) {
    if (n <= 1) return;
    f(n / 2);
    f(n / 2);
}
查看解答

时间:设规模 \(n\) 的调用次数为 \(T(n)\),则 \(T(n)=2T(n/2)+O(1)\)。画递归树:第 \(k\) 层有 \(2^{k}\) 个规模 \(n/2^{k}\) 的节点,规模降为 1 时停止,即层数 \(k=\log_2 n\),节点总数

\[ 1+2+4+\dots+2^{\log_2 n}=2^{\log_2 n+1}-1=2n-1=O(n) \]

空间:两处调用是先后顺序执行(非同时挂起),任意时刻栈中只有一条「根到当前节点」的路径,最大深度 \(\log_2 n+1\):

\[ S(n)=O(\log_2 n) \]

数值验证(\(n=8\)):调用节点 \(f(8)\) 1 个、\(f(4)\) 2 个、\(f(2)\) 4 个、\(f(1)\) 8 个,合计 \(15=2\times8-1\) ✓;最深路径 \(f(8)\to f(4)\to f(2)\to f(1)\) 共 4 帧 \(=\log_2 8+1\) ✓。

套路总结:\(T(n)=2T(n/2)+O(n)\)(如归并排序)→ \(O(n\log_2 n)\);\(T(n)=2T(n/2)+O(1)\)(本题)→ \(O(n)\)。加法项是 \(O(1)\) 还是 \(O(n)\) 决定档位。

1.5 本章考点总结

考点常考题型热度核心方法
逻辑结构与存储结构辨析选择题★★★★ 高频循环队列 / 哈希表 / 顺序表 = 存储层面;栈 / 队列 / 有序表 = 逻辑层面;运算「定义看逻辑、实现看存储」
算法五大特性选择题★★★有穷性区分算法与程序;输出至少一个;输入可零个
循环结构时间复杂度选择 / 大题第一步★★★★★ 每年必考频次法 + 求和法;乘常数 → \(\log_2 n\);加常数 → \(n\);内界依赖外层 → \(\sum i\)
递归复杂度选择 / 解答★★★★单分支画链(线性),多分支画树(指数);空间 = 递归深度
复杂度阶比较与机器速度估算选择 / 填空★★★阶序表;\(10^{9}\) 次 / 秒 → \(O(n^{2})\) 约 \(3\times10^{4}\),\(O(n\log_2 n)\) 约 \(4\times10^{7}\)
时空权衡大题设问★★★辅助数组换时间 or 对折双指针原地 \(O(1)\)
下一步本章过关标准:例题全部独立重做;自测 10 题中至少 8 题正确;能默写复杂度阶序表、逻辑结构四分类、存储结构四分类;任给一段循环代码能在 30 秒内说出大 O 并用一个具体 \(n\) 自检。然后进入 第 2 章 线性表(顺序表与链表)——408 数据结构大题的第一主战场。