@@ -26,7 +26,7 @@ B树是一种平衡的多叉树,通常我们说m阶的B树,它必须满足
26
26
27
27
B树中一个节点的子节点数目的最大值,用m表示,假如最大值为4,则为4阶,如图
28
28
29
- ![ ] ( https://gitee.com/wardseptember/images/raw/master /imgs/20200926202114.png)
29
+ ![ ] ( .. /imgs/20200926202114.png)
30
30
31
31
所有节点中,节点【13,16,19】拥有的子节点数目最多,四个子节点(灰色节点),所以可以定义上面的图片为4阶B树,现在懂什么是阶了吧
32
32
@@ -59,47 +59,47 @@ B树中一个节点的子节点数目的最大值,用m表示,假如最大值
59
59
- 1<=根节点元素个数<=4
60
60
- 2<=非根节点元素个数<=4
61
61
62
- ![ ] ( https://gitee.com/wardseptember/images/raw/master /imgs/20200926202239.png)
62
+ ![ ] ( .. /imgs/20200926202239.png)
63
63
64
- ![ ] ( https://gitee.com/wardseptember/images/raw/master /imgs/20200926202335.png)
64
+ ![ ] ( .. /imgs/20200926202335.png)
65
65
66
66
插入8
67
67
68
68
图(1)插入元素【8】后变为图(2),此时根节点元素个数为5,不符合 1<=根节点元素个数<=4,进行分裂(真实情况是先分裂,然后插入元素,这里是为了直观而先插入元素,下面的操作都一样,不再赘述),取节点中间元素【7】,加入到父节点,左右分裂为2个节点,如图(3)
69
69
70
- <div align =" center " > <img src =" https://gitee.com/wardseptember/images/raw/master /imgs/20201030151640.png" width =" 600 " /> </div ><br >
70
+ <div align =" center " > <img src =" .. /imgs/20201030151640.png" width =" 600 " /> </div ><br >
71
71
72
72
接着插入元素【5】,【11】,【17】时,不需要任何分裂操作,如图(4)
73
73
74
- ![ ] ( https://gitee.com/wardseptember/images/raw/master /imgs/20200926202722.png)
74
+ ![ ] ( .. /imgs/20200926202722.png)
75
75
76
76
插入元素【13】
77
77
78
- ![ ] ( https://gitee.com/wardseptember/images/raw/master /imgs/20200926202810.png)
78
+ ![ ] ( .. /imgs/20200926202810.png)
79
79
80
80
节点元素超出最大数量,进行分裂,提取中间元素【13】,插入到父节点当中,如图(6)
81
81
82
- ![ ] ( https://gitee.com/wardseptember/images/raw/master /imgs/20200926202839.png)
82
+ ![ ] ( .. /imgs/20200926202839.png)
83
83
84
84
85
85
86
86
接着插入元素【6】,【12】,【20】,【23】时,不需要任何分裂操作,如图(7)
87
87
88
- ![ ] ( https://gitee.com/wardseptember/images/raw/master /imgs/20200926202910.png)
88
+ ![ ] ( .. /imgs/20200926202910.png)
89
89
90
90
插入【26】时,最右的叶子结点空间满了,需要进行分裂操作,中间元素【20】上移到父节点中,注意通过上移中间元素,树最终还是保持平衡,分裂结果的结点存在2个关键字元素。
91
91
92
- ![ ] ( https://gitee.com/wardseptember/images/raw/master /imgs/20200926202928.png)
92
+ ![ ] ( .. /imgs/20200926202928.png)
93
93
94
94
95
95
96
96
插入【4】时,导致最左边的叶子结点被分裂,【4】恰好也是中间元素,上移到父节点中,然后元素【16】,【18】,【24】,【25】陆续插入不需要任何分裂操作
97
97
98
- ![ ] ( https://gitee.com/wardseptember/images/raw/master /imgs/20200926202952.png)
98
+ ![ ] ( .. /imgs/20200926202952.png)
99
99
100
100
最后,当插入【19】时,含有【14】,【16】,【17】,【18】的结点需要分裂,把中间元素【17】上移到父节点中,但是情况来了,父节点中空间已经满了,所以也要进行分裂,将父节点中的中间元素【13】上移到新形成的根结点中,这样具体插入操作的完成。
101
101
102
- ![ ] ( https://gitee.com/wardseptember/images/raw/master /imgs/20200926203022.png)
102
+ ![ ] ( .. /imgs/20200926203022.png)
103
103
104
104
## ** 删除**
105
105
@@ -115,27 +115,27 @@ B树中一个节点的子节点数目的最大值,用m表示,假如最大值
115
115
116
116
如图依次删除依次删除【8】,【20】,【18】,【5】
117
117
118
- ![ ] ( https://gitee.com/wardseptember/images/raw/master /imgs/20200926203135.png)
118
+ ![ ] ( .. /imgs/20200926203135.png)
119
119
120
120
首先删除元素【8】,当然首先查找【8】,【8】在一个叶子结点中,删除后该叶子结点元素个数为2,符合B树规则,操作很简单,咱们只需要移动【11】至原来【8】的位置,移动【12】至【11】的位置(也就是结点中删除元素后面的元素向前移动)
121
121
122
- ![ ] ( https://gitee.com/wardseptember/images/raw/master /imgs/20200926203202.png)
122
+ ![ ] ( .. /imgs/20200926203202.png)
123
123
124
124
下一步,删除【20】,因为【20】没有在叶子结点中,而是在中间结点中找到,咱们发现他的继承者【23】(字母升序的下个元素),将【23】上移到【20】的位置,然后将孩子结点中的【23】进行删除,这里恰好删除后,该孩子结点中元素个数大于2,无需进行合并操作。
125
125
126
- ![ ] ( https://gitee.com/wardseptember/images/raw/master /imgs/20200926203219.png)
126
+ ![ ] ( .. /imgs/20200926203219.png)
127
127
128
128
下一步删除【18】,【18】在叶子结点中,但是该结点中元素数目为2,删除导致只有1个元素,已经小于最小元素数目2,而由前面我们已经知道:如果其某个相邻兄弟结点中比较丰满(元素个数大于ceil(5/2)-1=2),则可以向父结点借一个元素,然后将最丰满的相邻兄弟结点中上移最后或最前一个元素到父节点中,在这个实例中,右相邻兄弟结点中比较丰满(3个元素大于2),所以先向父节点借一个元素【23】下移到该叶子结点中,代替原来【19】的位置,【19】前移;然【24】在相邻右兄弟结点中上移到父结点中,最后在相邻右兄弟结点中删除【24】,后面元素前移。
129
129
130
- <div align =" center " > <img src =" https://gitee.com/wardseptember/images/raw/master /imgs/20201030151726.png" width =" 600 " /> </div ><br >
130
+ <div align =" center " > <img src =" .. /imgs/20201030151726.png" width =" 600 " /> </div ><br >
131
131
132
132
最后一步删除【5】, 删除后会导致很多问题,因为【5】所在的结点数目刚好达标,刚好满足最小元素个数(ceil(5/2)-1=2),而相邻的兄弟结点也是同样的情况,删除一个元素都不能满足条件,所以需要该节点与某相邻兄弟结点进行合并操作;首先移动父结点中的元素(该元素在两个需要合并的两个结点元素之间)下移到其子结点中,然后将这两个结点进行合并成一个结点。所以在该实例中,咱们首先将父节点中的元素【4】下移到已经删除【5】而只有【6】的结点中,然后将含有【4】和【6】的结点和含有【1】,【3】的相邻兄弟结点进行合并成一个结点。
133
- ![ ] ( https://gitee.com/wardseptember/images/raw/master /imgs/20200926203302.png)
133
+ ![ ] ( .. /imgs/20200926203302.png)
134
134
135
135
136
136
137
137
也许你认为这样删除操作已经结束了,其实不然,在看看上图,对于这种特殊情况,你立即会发现父节点只包含一个元素【7】,没达标(因为非根节点包括叶子结点的元素K必须满足于2=<K<=4,而此处的K=1),这是不能够接受的。如果这个问题结点的相邻兄弟比较丰满,则可以向父结点借一个元素。而此时兄弟节点元素刚好为2,刚刚满足,只能进行合并,而根结点中的唯一元素【13】下移到子结点,这样,树的高度减少一层。
138
- ![ ] ( https://gitee.com/wardseptember/images/raw/master /imgs/20200926203320.png)
138
+ ![ ] ( .. /imgs/20200926203320.png)
139
139
140
140
看完插入,删除,想必也把B树的特征掌握了。
141
141
@@ -147,7 +147,7 @@ B树中一个节点的子节点数目的最大值,用m表示,假如最大值
147
147
148
148
外存储器即为磁盘读取,磁盘读取数据靠的是机械运动,每次读取数据花费的时间可以分为寻道时间、旋转延迟、传输时间三个部分,寻道时间指的是磁臂移动到指定磁道所需要的时间,主流磁盘一般在5ms以下;旋转延迟就是我们经常听说的磁盘转速,比如一个磁盘7200转,表示每分钟能转7200次,也就是说1秒钟能转120次,旋转延迟就是1/120/2 = 4.17ms;传输时间指的是从磁盘读出或将数据写入磁盘的时间,一般在零点几毫秒,相对于前两个时间可以忽略不计。那么访问一次磁盘的时间,即一次磁盘IO的时间约等于5+4.17 = 9ms左右,听起来还挺不错的,但要知道一台500 -MIPS的机器每秒可以执行5亿条指令,因为指令依靠的是电的性质,换句话说执行一次IO的时间可以执行40万条指令,数据库动辄十万百万乃至千万级数据,每次9毫秒的时间,显然是个灾难。下图是计算机硬件延迟的对比图,供大家参考:
149
149
150
- ![ ] ( https://gitee.com/wardseptember/images/raw/master /imgs/20200926210045.png)
150
+ ![ ] ( .. /imgs/20200926210045.png)
151
151
152
152
考虑到磁盘IO是非常高昂的操作,计算机操作系统做了一些优化,当一次IO时,不光把当前磁盘地址的数据,而是把相邻的数据也都读取到内存缓冲区内,因为局部预读性原理告诉我们,当计算机访问一个地址的数据的时候,与其相邻的数据也会很快被访问到。每一次IO读取的数据我们称之为一页(page)。具体一页有多大数据跟操作系统有关,一般为4k或8k,也就是我们读取一页内的数据时候,实际上才发生了一次IO,这个理论对于索引的数据结构设计非常有帮助。
153
153
@@ -171,7 +171,7 @@ B树中一个节点的子节点数目的最大值,用m表示,假如最大值
171
171
172
172
算法如下
173
173
174
- ![ ] ( https://gitee.com/wardseptember/images/raw/master /imgs/20200926210134.png)
174
+ ![ ] ( .. /imgs/20200926210134.png)
175
175
176
176
# B+树
177
177
@@ -207,11 +207,11 @@ B树中一个节点的子节点数目的最大值,用m表示,假如最大值
207
207
208
208
B+树如下:
209
209
210
- ![ ] ( https://gitee.com/wardseptember/images/raw/master /imgs/20200926212656.png)
210
+ ![ ] ( .. /imgs/20200926212656.png)
211
211
212
- ![ ] ( https://gitee.com/wardseptember/images/raw/master /imgs/20200926212831.png)
212
+ ![ ] ( .. /imgs/20200926212831.png)
213
213
214
- ![ ] ( https://gitee.com/wardseptember/images/raw/master /imgs/20200926213019.png)
214
+ ![ ] ( .. /imgs/20200926213019.png)
215
215
216
216
# 参考链接
217
217
0 commit comments