第1章 绪论 1
1.1 为什么要学习数据结构 1
1.2 抽象数据类型 3
1.3 数据结构 4
1.3.1 数据结构的基本术语 4
1.3.2 数据结构研究的三要素 5
1.4 算法与算法效率 6
1.4.1 算法举例 6
1.4.2 什么是算法 7
1.4.3 算法评价标准 8
1.4.4 算法描述方法 8
1.5 算法分析 10
1.5.1 算法比较举例 10
1.5.2 时间复杂度分析 11
1.5.3 常见循环的时间复杂度举例 12
习题 13
第2章 线性表 15
2.1 线性表的概念 15
2.1.1 线性表的定义 15
2.1.2 线性表的抽象数据类型定义 16
2.1.3 顺序表VS链表 16
2.2 顺序表的建立与判空 19
2.2.1 创建空的顺序表 19
2.2.2 判断顺序表为空 20
2.2.3 扩展延伸:通过调试理解算法 20
2.3 顺序表的插入和删除 22
2.3.1 插入算法 22
2.3.2 删除算法 24
2.3.3 小白实践:完整示例 25
2.4 顺序表的查找定位 26
2.4.1 查找算法 26
2.4.2 二分查找 26
2.5 单链表的建立与判空 29
2.5.1 建立单链表 29
2.5.2 链表的判空 29
2.5.3 用头插法建立单链表 29
2.5.4 用尾插法建立单链表 30
2.6 单链表的查找 31
2.7 单链表的插入 31
2.7.1 后插算法 31
2.7.2 前插算法 32
2.8 单链表的删除 33
2.8.1 按位置删除 33
2.8.2 按值删除 34
2.9 单循环链表 35
2.10 双链表和双循环链表 37
2.10.1 双链表 37
2.10.2 双循环链表 38
2.11 线性表的应用:一元多项式的表示和运算 39
2.12 线性表的应用:Josephus问题 41
2.13 动态链接库 43
2.13.1 动态链接库的概念 43
2.13.2 动态链接库的优缺点 43
2.13.3 动态链接库的构建与链接 43
习题 46
第3章 栈和队列 48
3.1 栈和队列的概念 48
3.1.1 栈和队列的定义 48
3.1.2 栈的抽象数据类型定义 49
3.1.3 栈混洗 49
3.2 顺序栈 50
3.2.1 创建空栈 51
3.2.2 判断栈空 51
3.2.3 进栈 51
3.2.4 出栈 52
3.2.5 取栈顶元素 52
3.3 链栈 53
3.3.1 创建空栈 53
3.3.2 判断栈空 53
3.3.3 进栈 54
3.3.4 出栈 54
3.3.5 取栈顶元素 54
3.4 栈的应用:进制转换 55
3.5 栈的应用:括号匹配 56
3.6 栈的应用:栈与递归 58
3.7 栈的应用:迷宫 60
3.8 栈的应用:表达式求值 64
3.9 循环队列 68
3.9.1 创建空队列 69
3.9.2 判断队列是否为空 70
3.9.3 入队 70
3.9.4 出队 70
3.9.5 取队头元素 71
3.10 链队列 71
3.10.1 创建空队列 71
3.10.2 判断队列是否为空 72
3.10.3 入队 72
3.10.4 出队 73
3.10.5 取队头元素 73
3.11 队列的应用:迷宫 73
3.12 队列的应用:农夫过河 76
3.13 双端队列 79
习题 80
第4章 树和二叉树 82
4.1 二叉树的概念 82
4.1.1 二叉树的基本形态和分类 82
4.1.2 二叉树的抽象数据类型定义 83
4.2 二叉树的数学性质 84
4.3 二叉树的深度优先遍历 85
4.4 二叉树的广度优先遍历 87
4.5 二叉树的重构 88
4.6 二叉树的交叉遍历 90
4.7 二叉树的顺序存储 92
4.8 二叉树的链式存储 93
4.9 二叉树的建立和遍历(递归算法) 94
4.9.1 二叉树的遍历 94
4.9.2 二叉树的建立 95
4.10 二叉树的建立和遍历(非递归算法) 96
4.10.1 二叉树建立的非递归实现 96
4.10.2 先序遍历的非递归实现 97
4.10.3 中序遍历的非递归实现 100
4.10.4 后序遍历的非递归实现 101
4.11 二叉树的其他操作 103
4.11.1 统计二叉树的叶子结点数 103
4.11.2 计算二叉树的深度 103
4.11.3 复制一棵二叉树 104
4.12 线索二叉树 104
4.12.1 线索二叉树的定义 104
4.12.2 建立线索二叉树 105
4.12.3 遍历线索二叉树 106
4.13 二叉树的应用:哈夫曼树与哈夫曼编码 107
4.14 树和森林 113
4.14.1 树和森林的概念 113
4.14.2 树和森林的遍历 113
4.14.3 树的存储表示 114
4.14.4 树、森林与二叉树的转换 115
习题 117
第5章 搜索树 119
5.1 二分查找判定树 119
5.2 二叉排序树的基本概念 120
5.3 二叉排序树的查找 121
5.4 二叉排序树的插入 122
5.5 二叉排序树的删除 123
5.6 平衡二叉树的概念 127
5.7 平衡二叉树的实例 128
5.8 平衡二叉树的4种调整和两个基本操作 128
5.9 AVL的插入操作 131
5.10 AVL的删除操作 136
5.11 红黑树的基本概念 139
5.12 红黑树的插入 140
5.13 红黑树的删除 144
习题 147
第6章 图 149
6.1 图的基本概念和抽象数据类型定义 149
6.1.1 图的基本概念 149
6.1.2 图的抽象数据类型定义 151
6.2 图的存储表示 152
6.2.1 邻接矩阵 152
6.2.2 邻接表 154
6.3 图的遍历 156
6.3.1 深度优先搜索 156
6.3.2 广度优先搜索 158
6.3.3 图的连通分支 160
6.3.4 图的层数 160
6.4 Prim算法 162
6.5 Kruskal算法 165
6.6 Dijkstra算法 169
6.7 拓扑排序 171
6.7.1 AOV网 171
6.7.2 拓扑排序算法 173
6.8 关键路径 175
6.8.1 AOE网 175
6.8.2 关键路径算法 176
6.9 六度空间问题 181
6.10 中国邮递员问题 183
6.10.1 问题的引入 183
6.10.2 相关知识点 184
6.10.3 算法流程 184
6.10.4 核心算法设计 185
6.10.5 具体实现 186
习题 191
第7章 字典 194
7.1 字典的基本概念 194
7.2 跳跃链表的基本概念 195
7.3 跳跃链表的建立和查找 196
7.3.1 空跳跃链表的建立 196
7.3.2 跳跃链表的查找 197
7.4 跳跃链表的插入和删除 198
7.4.1 跳跃链表的插入 198
7.4.2 跳跃链表的删除 199
7.5 散列表的基本概念 200
7.6 散列函数和冲突 201
7.6.1 散列函数 201
7.6.2 生日悖论 203
7.6.3 解决冲突的方法 204
7.7 散列表的建立、查找、插入和删除 207
7.7.1 散列表的建立 207
7.7.2 散列表的查找 208
7.7.3 散列表的插入 210
7.7.4 散列表的删除 211
7.8 Merkle树的基本概念 211
7.9 Merkle树的建立和查找比较 213
7.9.1 Merkle树的建立 213
7.9.2 Merkle树的查找比较 215
习题 217
第8章 排序 218
8.1 排序的基本概念 218
8.2 插入排序 219
8.2.1 直接插入排序 219
8.2.2 二分插入排序 221
8.2.3 Shell排序 223
8.3 选择排序 225
8.3.1 直接选择排序 225
8.3.2 堆排序 226
8.4 交换排序 230
8.4.1 冒泡排序 230
8.4.2 快速排序 231
8.5 基数排序 234
8.6 归并排序 237
8.7 排序算法的比较 240
习题 241
第9章 字符串 243
9.1 字符串的基本知识 243
9.1.1 字符串的基本概念 243
9.1.2 串的抽象数据类型定义 243
9.1.3 C库接口 244
9.1.4 正则表达式 245
9.2 朴素的模式匹配算法 245
9.3 KMP算法 247
9.3.1 KMP算法的思想 247
9.3.2 next表的存在性分析 248
9.3.3 构造next表 249
9.3.4 改进next表 250
9.4 Trie树 251
9.4.1 Trie树的基本概念 251
9.4.2 Trie树的基本操作 252
习题 254
参考文献 255