这是本文档旧的修订版!
绪论:数据结构与算法详解 (进阶版)
程序设计的核心公式(N.沃思):
程序 = 数据结构 (骨架) + 算法 (灵魂)
- 数据结构:是静态的。就像图书馆的书架,决定了书怎么放(是按首字母放,还是按类别放)。
- 算法:是动态的。就像图书管理员找书的流程(是从左往右一本本找,还是先查索引再找)。
第一部分:数据结构 (Data Structure)
1. 核心概念辨析
我们通过一个“学生信息管理系统”的例子来理解:
- 数据 (Data):计算机处理的符号总称。
- 数据元素 (Data Element):数据的基本单位(例:学生表中的一行记录)。
- 数据项 (Data Item):构成元素的最小单位(例:记录中的“学号”)。
- 数据对象 (Data Object):性质相同的数据元素的集合(例:所有学生的集合)。
2. 逻辑结构可视化
逻辑结构描述的是数据在思想上的关联。以下是四种基本结构的交互式演示:
集合结构 (Set)
松散关系,仅同属一个集合。
(例:操场上的同学)
线性结构 (Linear)
一对一,首尾相接。
(例:排队)
树状结构 (Tree)
一对多,层次分明。
(例:文件夹)
图形结构 (Graph)
多对多,错综复杂。
(例:交通网)
3. 存储结构:数据在“内存”中的样子
这是逻辑结构的物理实现。
3.1 顺序存储 vs 链式存储
| 特性 | 顺序存储 (数组) | 链式存储 (链表) |
|---|---|---|
| 物理位置 | 必须相邻 | 可以散落在内存各处 |
| 优点 | 查找快 (直接算地址),存储密度大 | 增删快 (改指针即可),不需预分配 |
| 缺点 | 插入删除需移动元素 | 查找慢 (必须从头找),指针占空间 |
3.2 进阶存储方式
- 索引存储:建立一张“目录表”。先查目录找到地址,再找内容。(类似字典的拼音索引)。
- 散列存储 (Hash):速度之王。
- 原理:通过公式直接算出地址。
- 例子:存 `105`,公式 `key % 10`,直接扔进 `5` 号房间。查找时直接去 `5` 号拿。
第二部分:算法 (Algorithm)
1. 算法效率度量 (Big O)
我们用 大O记号 表示随着数据量 $n$ 增大,耗时增长的趋势。
时间复杂度直观对比 (n 增大时)
- $O(1)$ 常数阶:无论数据多少,耗时不变。
- $O(n)$ 线性阶:数据翻倍,耗时翻倍。
- $O(n^2)$ 平方阶:数据翻倍,耗时变 4 倍(双层循环)。
- $O(\log_2 n)$ 对数阶:非常快(二分查找)。
第三部分:五大常用算法思想详解
1. 穷举法 (Brute Force)
- 核心:暴力破解,试遍所有可能。
- 优化:剪枝 (Pruning)。如果在搜索过程中发现当前路径不可能成功,就直接放弃,不再往下试(剪掉树枝)。
2. 分治法 (Divide and Conquer)
- 核心口诀:分而治之,各个击破。
- 三个步骤:
- 1. 分解 (Divide):将大问题分解为若干个规模较小的同类子问题。
- 2. 解决 (Conquer):递归地解决这些子问题。
- 3. 合并 (Combine):将子问题的解合并为原问题的解。
- 经典案例:归并排序、快速排序、二分查找。
大问题 (排序 8 个数)
↓ 拆分 (Divide)
子问题 A
子问题 B
↓ 递归解决 (Conquer)
A1
A2
|
B1
B2
↑ 合并结果 (Merge)
3. 动态规划 (Dynamic Programming)
- 核心:拒绝重复劳动。
- 原理:把大问题拆成小问题,但每个小问题的结果都存起来(通常存在数组或表中)。下次需要时,直接查表,不用重新算。
- 适用场景:求最值(最长路径、最大价值)、背包问题。
- 与分治法的区别:分治法的子问题是独立的;DP 的子问题是有重叠的。
普通递归 (傻算)
f(5) 需要算 f(4) 和 f(3)
f(4) 需要算 f(3) 和 f(2)
f(3) 被重复计算了!
f(4) 需要算 f(3) 和 f(2)
f(3) 被重复计算了!
动态规划 (记账)
算过 f(3) 吗?
算过 -> 直接查表
没算 -> 算出并填表
算过 -> 直接查表
没算 -> 算出并填表
f(1)
f(2)
f(3)
...
4. 贪心算法 (Greedy)
- 核心:目光短浅,只看眼前。
- 策略:在每一步选择中都采取在当前状态下最好(即最有利)的选择,希望最后堆出来的结果也是全局最好的。
- 局限:不能保证一定是全局最优解(比如走迷宫,一直往目标方向走可能会走进死胡同)。
- 经典案例:找零钱问题(优先用大面额)、霍夫曼编码。
5. 回溯法 (Backtracking)
- 核心:不撞南墙不回头。
- 策略:一条路走到黑,发现走不通了,就退回到上一个路口(回溯),换一条路继续走。
- 本质:深度优先搜索 (DFS) 的一种形式。
- 经典案例:八皇后问题、走迷宫、数独。
X 死路
√ 通路
先试上方(红),走不通 -> 回溯 -> 改走右方(绿)
总结
学习数据结构与算法,不是为了死记硬背代码,而是为了培养“计算思维”:
- 遇到复杂问题 → 分治
- 遇到重复计算 → 动态规划
- 需要快速试错 → 回溯
- 需要资源最优 → 贪心
希望这份可视化的笔记能帮助你建立起知识框架!