finish final
19
数据结构/img/图/ford1.png
Normal file
@@ -0,0 +1,19 @@
|
||||
<svg xmlns:xlink="http://www.w3.org/1999/xlink" width="6.965ex" height="2.843ex" style="vertical-align: -0.838ex;" viewBox="0 -863.1 2998.7 1223.9" role="img" focusable="false" xmlns="http://www.w3.org/2000/svg" aria-labelledby="MathJax-SVG-1-Title">
|
||||
<title id="MathJax-SVG-1-Title">w(u,v)</title>
|
||||
<defs aria-hidden="true">
|
||||
<path stroke-width="1" id="E1-MJMATHI-77" d="M580 385Q580 406 599 424T641 443Q659 443 674 425T690 368Q690 339 671 253Q656 197 644 161T609 80T554 12T482 -11Q438 -11 404 5T355 48Q354 47 352 44Q311 -11 252 -11Q226 -11 202 -5T155 14T118 53T104 116Q104 170 138 262T173 379Q173 380 173 381Q173 390 173 393T169 400T158 404H154Q131 404 112 385T82 344T65 302T57 280Q55 278 41 278H27Q21 284 21 287Q21 293 29 315T52 366T96 418T161 441Q204 441 227 416T250 358Q250 340 217 250T184 111Q184 65 205 46T258 26Q301 26 334 87L339 96V119Q339 122 339 128T340 136T341 143T342 152T345 165T348 182T354 206T362 238T373 281Q402 395 406 404Q419 431 449 431Q468 431 475 421T483 402Q483 389 454 274T422 142Q420 131 420 107V100Q420 85 423 71T442 42T487 26Q558 26 600 148Q609 171 620 213T632 273Q632 306 619 325T593 357T580 385Z"></path>
|
||||
<path stroke-width="1" id="E1-MJMAIN-28" d="M94 250Q94 319 104 381T127 488T164 576T202 643T244 695T277 729T302 750H315H319Q333 750 333 741Q333 738 316 720T275 667T226 581T184 443T167 250T184 58T225 -81T274 -167T316 -220T333 -241Q333 -250 318 -250H315H302L274 -226Q180 -141 137 -14T94 250Z"></path>
|
||||
<path stroke-width="1" id="E1-MJMATHI-75" d="M21 287Q21 295 30 318T55 370T99 420T158 442Q204 442 227 417T250 358Q250 340 216 246T182 105Q182 62 196 45T238 27T291 44T328 78L339 95Q341 99 377 247Q407 367 413 387T427 416Q444 431 463 431Q480 431 488 421T496 402L420 84Q419 79 419 68Q419 43 426 35T447 26Q469 29 482 57T512 145Q514 153 532 153Q551 153 551 144Q550 139 549 130T540 98T523 55T498 17T462 -8Q454 -10 438 -10Q372 -10 347 46Q345 45 336 36T318 21T296 6T267 -6T233 -11Q189 -11 155 7Q103 38 103 113Q103 170 138 262T173 379Q173 380 173 381Q173 390 173 393T169 400T158 404H154Q131 404 112 385T82 344T65 302T57 280Q55 278 41 278H27Q21 284 21 287Z"></path>
|
||||
<path stroke-width="1" id="E1-MJMAIN-2C" d="M78 35T78 60T94 103T137 121Q165 121 187 96T210 8Q210 -27 201 -60T180 -117T154 -158T130 -185T117 -194Q113 -194 104 -185T95 -172Q95 -168 106 -156T131 -126T157 -76T173 -3V9L172 8Q170 7 167 6T161 3T152 1T140 0Q113 0 96 17Z"></path>
|
||||
<path stroke-width="1" id="E1-MJMATHI-76" d="M173 380Q173 405 154 405Q130 405 104 376T61 287Q60 286 59 284T58 281T56 279T53 278T49 278T41 278H27Q21 284 21 287Q21 294 29 316T53 368T97 419T160 441Q202 441 225 417T249 361Q249 344 246 335Q246 329 231 291T200 202T182 113Q182 86 187 69Q200 26 250 26Q287 26 319 60T369 139T398 222T409 277Q409 300 401 317T383 343T365 361T357 383Q357 405 376 424T417 443Q436 443 451 425T467 367Q467 340 455 284T418 159T347 40T241 -11Q177 -11 139 22Q102 54 102 117Q102 148 110 181T151 298Q173 362 173 380Z"></path>
|
||||
<path stroke-width="1" id="E1-MJMAIN-29" d="M60 749L64 750Q69 750 74 750H86L114 726Q208 641 251 514T294 250Q294 182 284 119T261 12T224 -76T186 -143T145 -194T113 -227T90 -246Q87 -249 86 -250H74Q66 -250 63 -250T58 -247T55 -238Q56 -237 66 -225Q221 -64 221 250T66 725Q56 737 55 738Q55 746 60 749Z"></path>
|
||||
</defs>
|
||||
<g stroke="currentColor" fill="currentColor" stroke-width="0" transform="matrix(1 0 0 -1 0 0)" aria-hidden="true">
|
||||
<use xlink:href="#E1-MJMATHI-77" x="0" y="0"></use>
|
||||
<use xlink:href="#E1-MJMAIN-28" x="716" y="0"></use>
|
||||
<use xlink:href="#E1-MJMATHI-75" x="1106" y="0"></use>
|
||||
<use xlink:href="#E1-MJMAIN-2C" x="1678" y="0"></use>
|
||||
<use xlink:href="#E1-MJMATHI-76" x="2123" y="0"></use>
|
||||
<use xlink:href="#E1-MJMAIN-29" x="2609" y="0"></use>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.6 KiB |
BIN
数据结构/img/查找/b树插入1.jpg
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
数据结构/img/查找/b树插入2.jpg
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
数据结构/img/查找/b树插入3.jpg
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
数据结构/img/查找/b树插入4.jpg
Normal file
|
After Width: | Height: | Size: 33 KiB |
BIN
数据结构/img/树/avl旋转.png
Normal file
|
After Width: | Height: | Size: 72 KiB |
BIN
数据结构/img/矩阵/三对角矩阵.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
数据结构/img/矩阵/十字链表.jpg
Normal file
|
After Width: | Height: | Size: 44 KiB |
138
数据结构/图.md
Normal file
@@ -0,0 +1,138 @@
|
||||
# 图
|
||||
|
||||
## 概念
|
||||
|
||||
* 有向图
|
||||
* 无向图
|
||||
* 简单图:不存在重复边,不存在顶点到自身的边
|
||||
* 多重图:于简单图相对,可存在重复边,可存在顶点连到自身
|
||||
* 完全图(简单完全图):任意两点都有边(有向图则任意两点存在两条方向相反的边)
|
||||
* 子图
|
||||
* 连通:两顶点间存在路径则称为两点连通
|
||||
* 连通图:任意两点都连通的图
|
||||
* 连通分量(极大连通子图):再加一条边就不连通的子图
|
||||
* 极小连通子图:再删一条边就不连通的子图
|
||||
* 强连通图:有向图中,任意两点有向路径连通
|
||||
* 强连通分量:极大强连通子图
|
||||
* 生成树:包含图中所有顶点的极小连通子图
|
||||
* 生成森林:删除生成树的一条边即构成生成僧林
|
||||
* 入度:针对有向图
|
||||
* 出度:针对有向图
|
||||
* 度:针对无向图
|
||||
* 简单路径:顶点不重复出现的路径
|
||||
* 简单回路:只有起始点出现重复的路径
|
||||
|
||||
## 十字链表存储图
|
||||
|
||||
* 顶点节点作为链表表头
|
||||
* 顶点节点V引出两个链表,一条的元素为起始点为V的边,另一条的终点为V的边
|
||||
* 链表内元素为边
|
||||
|
||||
## 邻接多重表
|
||||
|
||||
* 每条边存储两遍,分别存储在两个顶点的链表中
|
||||
|
||||
## 图的遍历
|
||||
|
||||
* DFS
|
||||
* BFS
|
||||
|
||||
## 最小生成树
|
||||
|
||||
### Prim算法
|
||||
|
||||
* 初始化:选取任一顶点加入树T
|
||||
* 循环
|
||||
* 选取距离T中顶点距离最小的顶点A(A不在T中)
|
||||
* 将A加入T
|
||||
|
||||
### Kruskal算法
|
||||
|
||||
* 将边排序
|
||||
* 依次选取权值最小的两边
|
||||
|
||||
## 最短路径
|
||||
|
||||
### Dijkstra算法
|
||||
|
||||
#### 时间复杂度
|
||||
|
||||
* 普通版本:O(n^2^)
|
||||
* 堆优化:O(e*log(e))
|
||||
|
||||
#### 特点
|
||||
|
||||
* 不支持负权图
|
||||
|
||||
### Floyed算法(Floyd-Warshall算法)
|
||||
|
||||
#### 思想
|
||||
|
||||
* 插点法
|
||||
* 动态规划
|
||||
|
||||
#### 步骤
|
||||
|
||||
```c++
|
||||
for(k=1;k<=n;k++){
|
||||
for(i=1;i<=n;i++){
|
||||
for(j=1;j<=n;j++) {
|
||||
if(d[i][k]+d[k][j]<d[i][j]) {
|
||||
d[i][j]=d[i][k]+d[k][j];
|
||||
path[i][j]=path[i][k]; //path[i][j]代表i->j的路径里i的下一个节点
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 时间复杂度
|
||||
|
||||
* O(n^3^)
|
||||
|
||||
#### 特点
|
||||
|
||||
* 支持负权图
|
||||
* 可求出任意两点间的最短路径
|
||||
|
||||
### Bellman-Ford算法
|
||||
|
||||
#### 原理
|
||||
|
||||
* 最多循环n-1次即可找到最短路径
|
||||
* 循环体:
|
||||
* 对边集合 $E$ 中任意边,以$ w(u,v)$表示顶点 $u$出发到顶点  的边的权值,以 $d[v]$表示**当前**从起点 $s$ 到顶点 $v$ 的路径权值
|
||||
* 若存在边 $ w(u,v)$,使得:
|
||||
$d[v]>d[u]+w(u,v$)
|
||||
* 则更新$d[v]$值: $d[v]>d[u]+w(u,v$)
|
||||
|
||||
#### 特点
|
||||
|
||||
* 支持带负权的图
|
||||
* 遍历第n次可检测是否存在负权回路(若存在d[v]继续减少则存在)
|
||||
|
||||
#### 时间复杂度
|
||||
|
||||
* O(n*E)
|
||||
|
||||
## 关键路径
|
||||
|
||||
### AOE网
|
||||
|
||||
* 边代表活动,具有权值
|
||||
* 顶点代表事件(状态)
|
||||
|
||||
### AOV网
|
||||
|
||||
* 顶点代表活动
|
||||
* 边代表事件顺序
|
||||
|
||||
### 关键路径定义
|
||||
|
||||
* 整个工期的最短完成时间
|
||||
|
||||
#### 步骤
|
||||
|
||||
* 拓扑排序
|
||||
* 按拓扑排序的顺序求解节点的最早发生时间
|
||||
* 从汇点出发逆序求得各节点最晚发生时间
|
||||
45
数据结构/字符串.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# 字符串
|
||||
|
||||
## KMP算法
|
||||
|
||||
* 对模式串求得next数组,然后进行模式匹配
|
||||
|
||||
### Next数组
|
||||
|
||||
* 首位置空,一般用(-1或0填充),使得可直接使用当前匹配位置的next数组进行操作
|
||||
|
||||
* $$
|
||||
设模式串当前位置为i,模式串为S\\
|
||||
next[i]=S_{0...(i-1)}子串的最大公共前缀的末尾下标+1\\代表前next[i]-1个字符以匹配完成,直接用next[i]位置的字符继续匹配
|
||||
$$
|
||||
|
||||
* 原理
|
||||
|
||||
* 匹配到第i位发生不匹配,即代表前i-1位匹配,因此只要找到前i-1位后缀的最长公共前缀,即可从此位置开始继续匹配
|
||||
* 当模式串进行匹配第i位时发生不匹配时
|
||||
* 若i==0,则模式串直接右移从下一个字符开始从头匹配
|
||||
* 若i!=0,则模式串则继续匹配模式串next[i]位置的字符和当前位置主串的字符
|
||||
|
||||
### 优化
|
||||
|
||||
* 原理
|
||||
|
||||
* 若S~i~匹配失败,且S~next[i]~==S~i~,此时S~next[i]~必然匹配失败,因此我们可以省略必然匹配失败的值
|
||||
|
||||
* 因此新增nextval数组,next数组的第i位求法如下
|
||||
|
||||
```c++
|
||||
nextval[i]=get_nextval(i);
|
||||
int get_nextval(int i){
|
||||
int result=i;
|
||||
while(S[result]==S[i]){
|
||||
result=next[result];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
199
数据结构/排序.md
Normal file
@@ -0,0 +1,199 @@
|
||||
# 排序
|
||||
|
||||
## 插入类排序
|
||||
|
||||
### 直接插入排序
|
||||
|
||||
#### 时间复杂度
|
||||
|
||||
* 平均时间复杂度O(n^2^)
|
||||
* 最好时间复杂度O(n)
|
||||
|
||||
#### 空间复杂度
|
||||
|
||||
* O(1)
|
||||
|
||||
### 折半插入排序
|
||||
|
||||
#### 时间复杂度
|
||||
|
||||
* 最好时间复杂度O(n*log(n))
|
||||
* 平均时间复杂度O(n^2^)
|
||||
|
||||
#### 空间复杂度
|
||||
|
||||
* O(1)
|
||||
|
||||
### 希尔排序
|
||||
|
||||
#### 增量选取
|
||||
|
||||
* $\lfloor \frac {n}{2^k} \rfloor...2,1$
|
||||
* $2^k+1...3,1$
|
||||
|
||||
#### 空间复杂度
|
||||
|
||||
* O(1)
|
||||
|
||||
## 交换类排序
|
||||
|
||||
### 冒泡排序
|
||||
|
||||
#### 时间复杂度
|
||||
|
||||
* 平均时间复杂度O(n^2^)
|
||||
* 最好时间复杂度O(n)
|
||||
|
||||
#### 空间复杂度
|
||||
|
||||
* O(1)
|
||||
|
||||
### 快速排序
|
||||
|
||||
#### 时间复杂度
|
||||
|
||||
* 平均时间复杂度O(n*log(n))
|
||||
* 最好时间复杂度O(n*log(n))
|
||||
* 最坏时间复杂度O(n^2^)
|
||||
|
||||
#### 空间复杂度
|
||||
|
||||
* O(n*log(n))(需要递归栈)
|
||||
|
||||
## 选择类排序
|
||||
|
||||
### 直接选择排序
|
||||
|
||||
#### 时间复杂度
|
||||
|
||||
* O(n^2^)
|
||||
|
||||
#### 空间复杂度
|
||||
|
||||
* O(1)
|
||||
|
||||
### 堆排序
|
||||
|
||||
#### 堆
|
||||
|
||||
##### 初始化堆
|
||||
|
||||
1. 从底向上,找到第一个非叶子节点开始,向下浮动
|
||||
2. 直至到堆顶,初始化结束
|
||||
|
||||
##### 插入节点
|
||||
|
||||
1. 节点在堆底,进行上浮
|
||||
|
||||
##### 删除节点
|
||||
|
||||
1. 将尾节点位于栈顶,进行下浮操作
|
||||
|
||||
#### 排序过程
|
||||
|
||||
1. 初始化堆
|
||||
2. 将堆顶节点与尾节点交换,进行下浮操作
|
||||
3. 重复第二步,直至堆空
|
||||
|
||||
#### 时间复杂度
|
||||
|
||||
* O(n*log(n))
|
||||
|
||||
#### 空间复杂度
|
||||
|
||||
* O(1)
|
||||
|
||||
## 归并排序
|
||||
|
||||
### 二路归并排序
|
||||
|
||||
#### 时间复杂度
|
||||
|
||||
* O(n*log(n))
|
||||
|
||||
#### 空间复杂度
|
||||
|
||||
* O(n)
|
||||
|
||||
## 基数排序
|
||||
|
||||
#### 步骤
|
||||
|
||||
1. 按位遍历
|
||||
2. 第i趟遍历令第i位有序
|
||||
3. 循环主体:
|
||||
* 分成若干个桶,代表某一位的所有取值
|
||||
* 按顺序遍历数据时,将按位装桶
|
||||
* 最后按顺序依次桶中将数据提出
|
||||
|
||||
#### 时间复杂度
|
||||
|
||||
* O(d*(n+r))
|
||||
|
||||
#### 空间复杂度
|
||||
|
||||
* O(r)
|
||||
|
||||
## 内部排序比较
|
||||
|
||||
| 算法 | 最好时间复杂度 | 平均时间复杂度 | 最坏时间复杂度 | 空间复杂度 | 稳定性 |
|
||||
| ------------ | -------------- | -------------- | -------------- | ------------ | ------ |
|
||||
| 直接插入排序 | O(n) | O(n^2^`) | O(n^2^) | O(1) | 稳定 |
|
||||
| 冒泡排序 | O(n) | O(n^2^`) | O(n^2^) | O(1) | 稳定 |
|
||||
| 简单选择排序 | O(n^2^) | O(n^2^`) | O(n^2^) | O(1) | 不稳定 |
|
||||
| 希尔排序 | | | | O(1) | 不稳定 |
|
||||
| 快速排序 | O(n*log~2~(n)) | O(n*log~2~(n)) | O(n^2^) | O(log~2~(n)) | 不稳定 |
|
||||
| 堆排序 | O(n*log~2~(n)) | O(n*log~2~(n)) | O(n*log~2~(n)) | O(1) | 不稳定 |
|
||||
| 二路归并排序 | O(n*log~2~(n)) | O(n*log~2~(n)) | O(n*log~2~(n)) | O(n) | 稳定 |
|
||||
| 基数排序 | O(d*(n+r)) | O(d*(n+r)) | O(d*(n+r)) | O(r) | 稳定 |
|
||||
|
||||
## 外部排序
|
||||
|
||||
### 主要思想
|
||||
|
||||
1. 将待排序的数据段分成若干个小数据段(初始归并段),各段长度可能不同
|
||||
2. 对这些小数据段进行**内排序**(使用置换选择算法得到的初始归并段已经排好序了)
|
||||
3. 选出k组小数据段,进行归并排序(排序各段队首,其余部分留在外存)
|
||||
4. 排序完成后形成一条大归并段,接着对之后k条数据段进行排序,以此类推
|
||||
5. 再对大归并段进行归并排序,形成新的归并段,以此类推,直至所有数据排序完成
|
||||
|
||||
### 置换选择排序
|
||||
|
||||
* 用于生成初始归并段
|
||||
|
||||
#### 步骤
|
||||
|
||||
1. 先将输入记录充满缓冲区(可用于排序的主存)
|
||||
2. 输出此时缓冲区最小的可输出的数,再从输入记录中填充一个新数至缓冲区,若新数小于之前输出的数,则打上不可输出的标签
|
||||
3. 重复第二步,直至缓冲区内数都是不可输出数,得到一条初始归并段
|
||||
4. 清空缓冲区内不可输出的标签,回到第二步,以此类推,生成剩余归并段
|
||||
|
||||
### 最佳归并树
|
||||
|
||||
* 用于整个归并过程,其中包括若干次k路归并
|
||||
|
||||
* 使用归并树进行归并,每一个叶子节点代表一个初始归并段
|
||||
* 每一个非叶节点代表由子节点归并得到的新的归并树
|
||||
* 以归并段条数为权值,构造k路霍夫曼树
|
||||
* 构造方法:当归并段不足时,虚设若干个权值为0的叶子节点补足
|
||||
* 归并树$IO次数=2*WPL$,每条数据需要读写各一次
|
||||
* 使用最佳归并树可使IO次数最少
|
||||
|
||||
### 败者树
|
||||
|
||||
* 用于k路归并
|
||||
* 构造一个二叉树,其中叶子节点为归并段,父节点为子节点所代表归并段比较结果中的败者
|
||||
* 比较结果中的胜者不断上浮直至输出
|
||||
* 重新装入胜者所在归并段新的数据,进行上浮比较,构成新的败者树
|
||||
* 优点:每次比较只需log~2~(k)次
|
||||
|
||||
### 时间复杂度
|
||||
|
||||
#### 初始归并段进行k路归并
|
||||
|
||||
* 归并总趟数:$\lceil log_k(m) \rceil$
|
||||
* 每一次归并,所有记录进行两次I/O操作
|
||||
* 置换选择排序中,所有记录需要进行两次I/O操作
|
||||
* 置换选择排序中,选最值的复杂度视具体算法而定
|
||||
* k路归并败者树高度=$\lceil log_2(k) \rceil+1$,选出最值需要比较$\lceil log_2(k) \rceil$次
|
||||
* 建立k路归并败者树复杂度为O(k*log~2~(k))
|
||||
72
数据结构/数组矩阵与广义表.md
Normal file
@@ -0,0 +1,72 @@
|
||||
# 数组矩阵与广义表
|
||||
|
||||
## 矩阵压缩
|
||||
|
||||
* 对称矩阵
|
||||
|
||||
* 只需存储上半部分或下半部分
|
||||
|
||||
* 上三角矩阵/下三角矩阵
|
||||
|
||||
* 同对称矩阵
|
||||
|
||||
* 三对角矩阵
|
||||
|
||||
* 形如
|
||||
|
||||

|
||||
|
||||
* 自行寻找规律
|
||||
|
||||
## 稀疏矩阵存储
|
||||
|
||||
* 使用三元组存储
|
||||
|
||||
```c++
|
||||
struct Node{
|
||||
int value;
|
||||
int row;
|
||||
int col;
|
||||
}
|
||||
```
|
||||
|
||||
* 存储结构
|
||||
|
||||
* 邻接表
|
||||
* 十字链表法
|
||||
* 
|
||||
|
||||
## 广义表
|
||||
|
||||
### 定义
|
||||
|
||||
* 表元素可以是原子或广义表的线性表结构
|
||||
* 长度:最外层广义表的个数
|
||||
* 深度:对广义表进行展开,最大层数即为深度
|
||||
* 表头:广义表非空时,第一个元素即为表头
|
||||
* 表尾:广义表内除表头外剩余元素组成的广义表即为表尾
|
||||
|
||||
### 广义表举例
|
||||
|
||||
* A=()
|
||||
* 空表
|
||||
* 长度=1
|
||||
* 深度=1
|
||||
* B=(d,e)
|
||||
* 长度=2
|
||||
* 深度=1
|
||||
* C=(b,(c,d))
|
||||
* 长度=2
|
||||
* 深度=2
|
||||
* D=(B,C)
|
||||
* 元素全为广义表
|
||||
* 长度=2
|
||||
* 深度=3
|
||||
* E=(a,E)
|
||||
* 长度=2
|
||||
* 深度=∞
|
||||
* L=(a,(b,(c,(d)), e), f )
|
||||
* 长度=3
|
||||
* 深度=4
|
||||
* 表尾=((b,(c,(d)), e), f )
|
||||
|
||||
152
数据结构/查找.md
Normal file
@@ -0,0 +1,152 @@
|
||||
# 查找
|
||||
|
||||
## 概念
|
||||
|
||||
* 查找表:用于查找的数据结构
|
||||
* 静态查找表:建表后不进行修改的查找表
|
||||
* 顺序查找
|
||||
* 二分查找(折半查找)
|
||||
* 散列查找
|
||||
* 动态查找表:建表后需进行修改的查找表
|
||||
* 二叉排序树
|
||||
* 二叉平衡树
|
||||
* B树
|
||||
* B+树
|
||||
* 散列查找
|
||||
|
||||
* 查找长度:查找过程中比较关键字的次数
|
||||
|
||||
## 分块查找
|
||||
|
||||
* 将查找表分为若干子块
|
||||
* 子块间有序(如:若子块A<子块B,则A中所有元素都小于B中任意元素)
|
||||
* 块内数据无序
|
||||
* 块间使用索引表查找
|
||||
* 块内使用顺序查找
|
||||
|
||||
## B树
|
||||
|
||||
### 特性
|
||||
|
||||
* 每个节点最多m棵子树,至多含有m-1个关键字,即在关键字两端分叉
|
||||
* B树每个节点都可以存放关键字(数据)
|
||||
* 非叶根节点至少有两颗子树(即至少存在节点左右两端的两个终端节点代表查找失败)
|
||||
* 除根节点外,所有非叶子节点至少含有$\lceil \frac m2 \rceil$个子树,即含有$\lceil \frac m2 \rceil -1$个关键字
|
||||
* 叶节点(终端节点)不存放信息,代表查询失败
|
||||
* 对于关键字树为n,高度为h(不包括终端节点所在的那一层),阶数为m的B树
|
||||
$ log_m(n+1) \leq h \leq log_{\lceil \frac m2 \rceil}(\frac {n+1}2)+1$
|
||||
|
||||
### 查找
|
||||
|
||||
* B树节点存储在磁盘,将节点加载置内存后,使用顺序查找或折半查找查找关键字
|
||||
|
||||
### 插入
|
||||
|
||||
* 当节点内关键字数目n=m时,从中间左右分叉,将中间节点添入父节点
|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
### 删除
|
||||
|
||||
* 当删除关键字后,节点数=$\lceil \frac m2 \rceil-1$时
|
||||
* 如果兄弟结点关键字个数大于$\lceil \frac m2 \rceil-1$,则父结点中的关键字下移到该结点,兄弟结点中的一个关键字上移,删除操作结束。
|
||||
* 将父结点中的关键字下移与当前结点及它的兄弟结点中的关键字合并,形成一个新的结点。原父结点中的关键字的两个孩子指针就变成了一个孩子指针,指向这个新结点。
|
||||
* 然后当前结点的指针指向父结点,重复上述步骤
|
||||
|
||||
## B+树
|
||||
|
||||
### 特点
|
||||
|
||||
* 每个节点最多m棵子树,至多含有m个关键字,即仅在关键字一段分叉
|
||||
* B+树非叶子节点
|
||||
* 非叶根节点至少有两颗子树
|
||||
* 除根节点外,所有非叶子节点至少含有$\lceil \frac m2 \rceil$个子树,即含有$\lceil \frac m2 \rceil $个关键字
|
||||
* 叶节点包含所有关键字和指向记录的指针,同时所有叶节点用指针串联
|
||||
* B+树中,非叶节点仅用于索引下一颗子树
|
||||
* 可执行顺序查找或多路查找
|
||||
|
||||
## B树与B+树区别
|
||||
|
||||
| | B树 | B+树 |
|
||||
| --------------------- | ------------------------------------------ | -------------------------------------- |
|
||||
| n个关键字对应子树数目 | n+1 | n |
|
||||
| 节点内关键字数目范围 | $\lceil \frac m2 \rceil -1\leq n \leq m-1$ | $\lceil \frac m2 \rceil \leq n \leq m$ |
|
||||
| 非叶节点内容 | 包含关键字和数据 | 仅包含指向下一子树的索引 |
|
||||
|
||||
## 散列查找
|
||||
|
||||
### 散列函数
|
||||
|
||||
#### 直接定址法
|
||||
|
||||
* $H(key)=a*key+b$
|
||||
* 优点
|
||||
* 简单,不会冲突
|
||||
* 缺点
|
||||
* 关键字分布不连续的情况下会导致空间浪费
|
||||
* 适用场景
|
||||
* 关键字分布连续
|
||||
|
||||
#### 除留余数法
|
||||
|
||||
* $H(key)=key \bmod p$
|
||||
* p的选取:选择不大于散列表长但最接近的指数p
|
||||
* 最简单
|
||||
* 最常用
|
||||
|
||||
#### 数字分析法
|
||||
|
||||
* 通过分析数据,选取数码分布最均匀的若干位作为散列地址
|
||||
* 适用场景
|
||||
* 已知的关键字集合
|
||||
* 缺点
|
||||
* 若更换了关键字,需要重新构造散列函数
|
||||
|
||||
#### 平方取中法
|
||||
|
||||
* 对关键字进行平方后,选择中间的若干位
|
||||
* 优点
|
||||
* 分布较均匀
|
||||
|
||||
### 冲突处理
|
||||
|
||||
#### 开放定址法
|
||||
|
||||
* 重新查找新的散列地址
|
||||
* $H_i=(H(key)+d_i) \bmod m\ 其中m为散列表长$
|
||||
|
||||
##### 增量选择方式
|
||||
|
||||
* 线性探测法
|
||||
* $d_i=0,1,2,3...m-1$
|
||||
* 缺陷
|
||||
* 相邻散列地址容易堆积大量元素,造成查找效率降低
|
||||
* 平方探测法
|
||||
* $d_i=0^2,1^2,-1^2,2^2,-2^2,3^2,-3^2...k^2,-k^2...$
|
||||
* 其中m需满足m为可表示成4k+3的素数
|
||||
* 缺点
|
||||
* 不能探测到散列表内所有单元,但至少能探测到一半
|
||||
* 优点
|
||||
* 能避免堆积
|
||||
* 再散列法
|
||||
* $d_i=i*H_2(key)$
|
||||
* 优点
|
||||
* 最多探测m-1次就能探测所有散列表位置
|
||||
* 伪随机序列法
|
||||
* $d_i=伪随机序列$
|
||||
|
||||
#### 拉链法
|
||||
|
||||
* 使用链表存储所有冲突的关键字
|
||||
|
||||
### 查找效率
|
||||
|
||||
#### 决定因素
|
||||
|
||||
* 散列函数
|
||||
* 处理冲突
|
||||
* 装填因子$\alpha=\frac {表中记录数n}{散列表长度m}$
|
||||
* 装填因子越大,代表越容易发生冲突
|
||||
|
||||
29
数据结构/栈和队列.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# 栈和队列
|
||||
|
||||
## 栈的基本概念
|
||||
|
||||
* 线性表
|
||||
|
||||
* n个元素以某种顺序进栈,并以任意顺序出栈,获得元素的排列组合数目为卡特兰数
|
||||
$$
|
||||
N=\frac{1}{n+1}C^n_{2n}
|
||||
$$
|
||||
|
||||
## 队列的基本概念
|
||||
|
||||
* 线性表
|
||||
|
||||
## 循环队列
|
||||
|
||||
* 损失一个存储空间
|
||||
|
||||
## 难点问题
|
||||
|
||||
### 中缀表达式转后缀表达式
|
||||
|
||||
* 扫描表达式,若字符为数字,直接输出
|
||||
* 若为左括号,直接进栈
|
||||
* 若为右括号,令栈内元素输出,直至遇到左括号
|
||||
* 若为运算符,将栈顶元素输出直至栈顶元素优先级低于或等于当前运算符,入栈
|
||||
* 运算符优先级:**(**高于 ***/** 高于 **+-** 高于 **)**
|
||||
|
||||
123
数据结构/树.md
Normal file
@@ -0,0 +1,123 @@
|
||||
# 树
|
||||
|
||||
## 基本概念
|
||||
|
||||
* 节点的度:一个节点的孩子个数称为节点的**度**
|
||||
* 树的度:树中最大节点的度
|
||||
* 深度:从根节点开始自顶向下计算
|
||||
* 高度:从叶节点开始自底向上计算
|
||||
|
||||
## 树的性质
|
||||
|
||||
* 树的节点树=所有节点的度+1
|
||||
|
||||
* 度为m的树第i层至多有m^i-1^个节点
|
||||
|
||||
* 高度为h的m叉树最多有(m^h^-1)/(m-1)个节点(通过等比数列求和得到)
|
||||
|
||||
* 具有n个节点的m叉树最小高度为$\lceil log_m(n(m-1)+1) \rceil$
|
||||
推导过程:
|
||||
$$
|
||||
高度最小的情况下,每个节点的度数都尽可能多\\
|
||||
因此高度为h的m叉树在此情况下的节点数n满足以下条件\\
|
||||
\frac{(m^{h-1}-1)}{(m-1)} < n \leq \frac{(m^{h}-1)}{(m-1)}\\
|
||||
=>\ log_m(n(m-1)+1)\leq h < log_m(n(m-1)+1)+1\\
|
||||
=>\ h=\lceil log_m(n(m-1)+1) \rceil
|
||||
$$
|
||||
|
||||
|
||||
## 二叉树
|
||||
|
||||
### 二叉树性质
|
||||
|
||||
* 非空二叉树叶子节点的数目等于度为2的节点数+1
|
||||
推导过程:
|
||||
$$
|
||||
设度为0的节点数为n_0, 度为1的节点数为n_1,度为2的节点数为n_2,总结点数为n\\
|
||||
n=n_0+n_1+n_2\\
|
||||
n=n_1+n_2*2+1\\
|
||||
=>\ n_0=n_2+1
|
||||
$$
|
||||
|
||||
* 非空二叉树第k层至多有2^k-1^个节点
|
||||
|
||||
* 高度为h的二叉树最多有2^h^-1个节点
|
||||
|
||||
* 结点数为n的完全二叉树高度$h=\lceil log_2(n+1) \rceil或\lfloor log_2(n) \rfloor+1$
|
||||
|
||||
### 特殊二叉树
|
||||
|
||||
#### 满二叉树
|
||||
|
||||
* 高度为h,且具有2^h^-1个结点的二叉树称为满二叉树
|
||||
|
||||
#### 完全二叉树
|
||||
|
||||
* 高度为h的二叉树,最多仅有第h层未满,且第h层节点从左往右排(等价于满二叉树第h层右侧抽取掉部分节点),该树称为完全二叉树
|
||||
|
||||
#### 二叉排序树
|
||||
|
||||
* 左子树节点小于根节点,右子树节点大于根节点
|
||||
|
||||
#### 平衡二叉树
|
||||
|
||||
* 任一节点的左子树与右子树的深度之差的绝对值不超过1
|
||||
|
||||
## 线索二叉树
|
||||
|
||||
### 构造说明
|
||||
|
||||
* 对于某一结点,若无左子树,则该节点左指针指向其直接前驱节点
|
||||
* 对于某一结点,若无右子树,则该节点右指针指向其直接后继节点
|
||||
* 使用标记位tag标记左右指针为左右子树还是前驱后继节点
|
||||
|
||||
## 森林
|
||||
|
||||
### 森林与树的转换
|
||||
|
||||
* 将兄弟节点转换成右子树
|
||||
* 子节点转换为左子树
|
||||
* 森林中的所有树看作是兄弟
|
||||
|
||||
### 森林的遍历
|
||||
|
||||
#### 先序遍历
|
||||
|
||||
* 等价于先序遍历森林转换后的二叉树
|
||||
|
||||
#### 后序遍历/中序遍历
|
||||
|
||||
* 等价于中序遍历森林转换后的二叉树
|
||||
|
||||
## 二叉排序树
|
||||
|
||||
### 平衡二叉树
|
||||
|
||||
#### 旋转
|
||||
|
||||
* RR旋转(左单旋转)
|
||||
* 条件:右子树的右子树插入了新节点导致失衡
|
||||
* LL旋转(右单旋转)
|
||||
* 条件:左子树的左子树插入了新节点导致失衡
|
||||
* LR旋转(先左后右旋转)
|
||||
* 条件:左节点的右子树插入新节点导致失衡
|
||||
* RL旋转(先右后左旋转)
|
||||
* 条件:右节点的左子树插入了新节点导致失衡
|
||||
|
||||

|
||||
|
||||
## 哈夫曼树
|
||||
|
||||
### 概念
|
||||
|
||||
* 又称最优二叉树
|
||||
|
||||
### 构造
|
||||
|
||||
* 找到权值最小的两个子树拼接成新的子树
|
||||
* 重复上述步骤
|
||||
|
||||
### 哈夫曼树的带权路径长度(WPL)
|
||||
|
||||
* 某一叶子节点的WPL=该点权值*该点到根节点的路径长
|
||||
|
||||
50
数据结构/线性表.md
Normal file
@@ -0,0 +1,50 @@
|
||||
# 线性表
|
||||
|
||||
## 定义
|
||||
|
||||
* 具有相同数据类型的n个数据元素的有序序列
|
||||
* 第一个数据元素称为表头元素
|
||||
* 最后一个数据元素称为表尾元素
|
||||
* 每个元素仅有一个直接后继
|
||||
|
||||
## 特点
|
||||
|
||||
* 个数有限
|
||||
* 逻辑上具有顺序性
|
||||
* 每个元素都是数据元素
|
||||
* 表中元素数据类型都相同
|
||||
|
||||
## 存储结构
|
||||
|
||||
* 顺序表
|
||||
* 链表
|
||||
* 单向链表
|
||||
* 带头结点的单链表
|
||||
* 不带头结点的单链表
|
||||
* 双向链表
|
||||
* 循环单向链表
|
||||
* 循环双向链表
|
||||
* 静态链表:使用数组实现
|
||||
* 静态链表中的指针指数组下标
|
||||
|
||||
### 比较
|
||||
|
||||
| | 顺序表 | 链表 |
|
||||
| ------------------- | ------------------------ | ---------------- |
|
||||
| 存储分配 | 一次性分配内存 | 多次分配 |
|
||||
| 存储密度 | =1 | <1(包含指针域) |
|
||||
| 存取方式 | 随机存取 | 顺序存取 |
|
||||
| 插入/删除移动元素数 | 平均移动n/2个元素 | 不需要移动元素 |
|
||||
| 插入/删除时间复杂度 | $O(\frac {n-1}{2})=O(n)$ | $O(1)$ |
|
||||
|
||||
## 单链表
|
||||
|
||||
### 建立链表
|
||||
|
||||
#### 头插法
|
||||
|
||||
* 将新节点插入表头
|
||||
|
||||
#### 尾插法
|
||||
|
||||
* 将新节点插入表尾
|
||||
39
数据结构/绪论.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# 绪论
|
||||
|
||||
## 数据结构基本概念
|
||||
|
||||
* 数据:所有输入计算机程序的符号的总称,如整数,字符串等
|
||||
* 数据元素:数据的基本单位,可由若干个数据项构成,可类比面向对象语言中的**类的实例**
|
||||
* 数据对象:同一性质的数据元素的集合,可类别面向对象语言中的**类**
|
||||
* 数据结构:有特定关系的数据元素的集合
|
||||
* 存储结构/物理结构:数据的逻辑结构在计算机中的存储
|
||||
* 顺序存储
|
||||
* 链式存储
|
||||
* 索引存储
|
||||
* 散列存储
|
||||
* 逻辑结构:对数据见关系的描述
|
||||
* 线性结构
|
||||
* 非线性结构
|
||||
* 树
|
||||
* 图
|
||||
* 运算逻辑
|
||||
* 数据类型
|
||||
* 原子类型
|
||||
* 结构类型
|
||||
* 抽象数据类型
|
||||
|
||||
## 算法基本概念
|
||||
|
||||
* 算法:有限的确定计算序列
|
||||
* 算法的特性
|
||||
* 有穷性
|
||||
* 确定性
|
||||
* 输入
|
||||
* 输出
|
||||
* 可行性
|
||||
* 算法的设计目标
|
||||
* 正确性
|
||||
* 可读性
|
||||
* 健壮性
|
||||
* 高效率
|
||||
* 低存储
|
||||
@@ -229,4 +229,6 @@
|
||||
* GFLOPS:每秒执行的10^9^浮点运算数
|
||||
* TFLOPS:每秒执行的10^12^浮点运算数
|
||||
* PFLOPS:每秒执行的10^15^浮点运算数
|
||||
* EFLOPS:每秒执行的10^18^浮点运算数
|
||||
* ZFLOPS:每秒执行的10^21^浮点运算数
|
||||
* IPC:每一个时钟周期执行的指令数
|
||||