1. 什么是数据结构?
(1)定义
数据结构是相互之间存在特定关系的数据元素的集合。它是计算机存储、组织数据的方式,研究数据的逻辑结构、物理结构以及它们之间的相互关系,并对这种结构定义相适应的运算,设计出相应的算法。
(2)三要素
- 逻辑结构:数据元素之间的逻辑关系,包括:
- 线性结构(线性表、栈、队列)
- 树形结构
- 图状结构
- 集合
- 物理结构(存储结构):数据在计算机中的存储方式,包括:
- 顺序存储
- 链式存储
- 哈希存储
- 索引存储
- 数据运算:对数据的基本操作,包括:
- 插入
- 删除
- 查找
- 排序
- 遍历
2. 时间复杂度O的意义
(1)时间复杂度
表示算法执行时间随数据规模增长的趋势,关注最高阶项(如O(n2))。
(2)空间复杂度
算法运行所需辅助空间的大小,如递归栈空间(O(n))。
(3)原址性
若算法仅需O(1)辅助空间,称为“原址工作”(如冒泡排序)。
3. 循环与递归的对比
特性 | 循环 | 递归 |
---|---|---|
优点 | 执行效率高,无额外栈开销 | 代码简洁,逻辑清晰(如树遍历) |
缺点 | 复杂问题代码冗长(如汉诺塔) | 栈溢出风险,重复计算(斐波那契数列) |
适用场景 | 线性迭代(数组遍历) | 分治问题(快速排序、二叉树操作) |
4. 顺序表与链表的区别
对比维度 | 顺序表 | 链表 |
---|---|---|
存取方式 | 随机存取(通过下标直接访问) | 顺序存取(需从头结点遍历) |
存储结构 | 物理结构与逻辑结构一致(连续内存) | 物理结构离散,逻辑通过指针表示 |
插入/删除 | 平均O(n)(需移动元素) | 平均O(1)(仅修改指针) |
空间分配 | 静态分配(需预判数据规模) | 动态分配(按需申请内存) |
5. 头指针与头结点的区别
(1)头指针
- 指向链表第一个结点的指针,必须存在。
- 空链表时指向
NULL
。
(2)头结点
- 位于第一个数据结点前的辅助结点,数据域通常无意义。
- 作用:简化插入/删除操作(避免处理头指针变更)。
6. 栈与队列的核心区别
结构 | 操作规则 | 应用场景 |
---|---|---|
栈 | 后进先出(LIFO) | 函数调用栈、括号匹配、表达式求值 |
队列 | 先进先出(FIFO) | 任务调度、缓冲区管理、BFS算法 |
7. 二叉树的性质与遍历
(1)性质
- 第i层最多有2i−1个结点。
- 深度为k的二叉树最多有2k−1个结点。
(2)遍历方式
- 先序:根→左→右(用于复制树结构)
- 中序:左→根→右(二叉搜索树有序输出)
- 后序:左→右→根(用于释放树内存)
8. 图的存储方式对比
存储方式 | 优点 | 缺点 |
---|---|---|
邻接矩阵 | 快速判断两结点是否邻接 | 空间复杂度高(O(n2)) |
邻接表 | 节省空间(稀疏图) | 查找边效率低(O(n)) |
9. 动态规划解题步骤
- 定义状态:明确dp[i]或dp[i][j]的含义。
- 状态转移方程:递推关系式。
- 初始化:边界条件赋值。
- 计算顺序:确保子问题先求解。
- 结果提取:从dp表中获取最终解。
10. 哈希表负载因子与性能关系
(1)负载因子
α=哈希表大小已存元素数
(2)性能关系
- α越大,冲突概率越高,查询效率下降。
- 解决策略:动态扩容(如Java HashMap的默认负载因子0.75)。
11. 字符串匹配算法
(1)KMP算法
通过前缀函数避免重复匹配,时间复杂度O(n+m)。
(2)BM算法
从模式串尾部匹配,利用坏字符和好后缀规则加速。
12. 高级树结构
(1)B树/B+树
多路平衡树,用于数据库索引。
(2)Trie树
前缀树,适用于字典检索、自动补全。
13. 外部排序与多路归并
(1)问题场景
数据量超过内存容量时如何排序。
(2)解决方案
- 将数据分块排序后存入磁盘。
- 使用多路归并减少I/O次数。
14. 贪心算法适用条件
(1)最优子结构
全局最优包含局部最优。
(2)贪心选择性质
每一步选择不影响后续决策。