数据结构基本概念
不直接考察,只是理清考题中的数据结构
一、数据结构
存储、组织和管理数据的方式——> 决定数据的存储方式,影响数据访问和操作的效率
1.1 分类
二、算法
解决问题的一系列步骤或方法——> 操作数据结构,实现具体功能
e.g
-
用数组实现栈 → 可以快速访问栈顶
-
用链表实现队列 → 插入删除都很快
-
用堆实现优先队列 → 可以快速找最大/最小值
-
用图 + BFS → 可以找最短路径
算法基本概念
考察复杂度分析
一、算法
一个明确规定了操作步骤的有限指令集——>计算函数、处理数据、解决一个特定问题或执行某个任务
算法 的基本属性:
- 明确性:每一步骤必须有明确且不含糊的定义。
- 有输入和输出:算法 应有 0 个或更多的 输入 和 1 个或更多的 输出。输入 是在 算法 开始之前提供的,而 输出 是在 算法 结束时产生的。
- 有限性:如果 算法 在执行完有限步骤后终止,那么它就是 有限的。换句话说,一个 算法 必须总是在执行有限次操作后结束。
- 可行性:算法 中的每一步都应该是简单且基本的,这样它们可以在有限的时间内完成并由计算机执行。
- 独立性:算法 的指令应该有普适性,也就是说,它们不应依赖于任何特定的编程语言或模型。相反,算法 应该足够通用,可以在任何编程环境中实现。
二、效率度量
2.1 时间复杂度
衡量算法执行时间随输入规模增长的变化趋势的指标,不关心算法跑了多少毫秒,只关心当输入数据量变大时,执行时间会 “以多快的速度增长”
常见时间复杂度(按增长速度从慢到快排序)
| 复杂度 | 名称 | 例子 | 特点 |
|---|---|---|---|
| O(1) | 常数阶 | 访问数组第 k 个元素 | 执行时间和 n 无关,固定次数 |
| O(logn) | 对数阶 | 二分查找 | 每次操作让问题规模减半,增长极慢 |
| O(n) | 线性阶 | 遍历数组 | 执行时间和 n 成正比 |
| O(nlogn) | 线性对数阶 | 归并排序、快速排序 | 比线性阶慢,但比平方阶快 |
| O(n²) | 平方阶 | 冒泡排序、双重循环 | 执行时间和 n 的平方成正比 |
| O(2ⁿ) | 指数阶 | 斐波那契递归暴力解法 | 增长极快,n 稍大就无法运行 |
通俗例子理解
-
O(1):查字典直接翻到目录页,不管字典有 100 页还是 10000 页,都是 1 步到位。 -
O(logn):猜数字游戏(1~100),每次猜中间数排除一半,最多猜 7 次(log₂100≈7),n 翻倍时,次数只多 1。 -
O(n):在 100 个人里找一个人,最坏要挨个问 100 次;n 变成 200,最坏就要问 200 次,时间跟着 n 翻倍。 -
O(n²):两两握手,10 个人要握 45 次(10×9/2);20 个人要握 190 次,n 翻倍,时间变成原来的 4 倍。
2.2 空间复杂度
衡量算法运行过程中,临时占用的额外 内存 随输入规模增长的变化趋势的指标,核心是看 “额外用了多少内存”,不包括输入数据本身的内存
组成
-
固定部分
- 包括常量、程序代码本身、简单变量、常量数组等。
- 这一部分的空间大小与输入数据规模无关,通常记为 O(1)O(1) 。
-
可变部分
-
随着输入数据量的变化而变化的空间,主要包括:
-
输入数据本身(如数组、链表)
-
辅助空间(如临时数组、栈、队列等)
-
递归 调用栈(递归深度对空间占用有直接影响)
-
-
常见空间复杂度
常见的 空间复杂度(按增长速度排序)有:
| 空间复杂度 | 描述 | 示例 |
|---|---|---|
| O(1)O(1) | 使用常量额外空间 | 交换两个变量、求最大值/最小值 |
| O(n)O(n) | 需要与输入规模成线性关系的额外空间 | 复制数组、链表逆序 |
| O(n2)O(n2) | 二维数组或矩阵存储 | Floyd-Warshall 算法的距离矩阵 |
| O(logn)O(logn) | 递归调用栈空间 | 二分查找的递归实现、平衡二叉树的遍历 |