多路平衡查找树 --- B(B-)树
1 簡(jiǎn)介
可以用階數(shù)來(lái)描述B樹(shù), 一棵M階B樹(shù)代表著該B樹(shù)最多有M個(gè)孩子節(jié)點(diǎn). 如果M為2, 那么該B樹(shù)就是一棵二叉搜索樹(shù). 一棵M階B樹(shù)具有以下性質(zhì):
1. 每個(gè)節(jié)點(diǎn)最多有M - 1個(gè)關(guān)鍵字.?跟普通的樹(shù)不同, B樹(shù)的關(guān)鍵字有多個(gè).
2. 根節(jié)點(diǎn)最少可以只有一個(gè)關(guān)鍵字.
3. 非根節(jié)點(diǎn)至少有k個(gè)關(guān)鍵字, 這里的k是指ceil(M / 2) - 1.(這里面的ceil是指大于等于參數(shù)的最小整數(shù), 從下面插入操作分析可知, 葉子節(jié)點(diǎn)都是由父節(jié)點(diǎn)分裂而來(lái), 而分裂的條件就是分裂前節(jié)點(diǎn)總數(shù)已經(jīng)達(dá)到了M)
4. 每個(gè)節(jié)點(diǎn)中的關(guān)鍵字都按照從小到大的順序排列, 每個(gè)關(guān)鍵字在左子樹(shù)中的所有關(guān)鍵字都小于它本身的關(guān)鍵字, 右子樹(shù)的都大于它本身關(guān)鍵字.
5. 所有葉子節(jié)點(diǎn)都位于同一層, 或者說(shuō)根節(jié)點(diǎn)到每個(gè)葉子節(jié)點(diǎn)的長(zhǎng)度都相同.
2 插入操作
一棵M階樹(shù)的插入操作可以總結(jié)為以下步驟:
1. 根據(jù)要插入的key的值, 找到對(duì)應(yīng)的葉子節(jié)點(diǎn)(一定要注意是葉子節(jié)點(diǎn))
2. 如果被插入后的節(jié)點(diǎn)的key總數(shù)達(dá)到了M, 就需要對(duì)該節(jié)點(diǎn), 按照key序列的中間左右分開(kāi)進(jìn)行分裂, 中間的key插入其父節(jié)點(diǎn).
3. 對(duì)父節(jié)點(diǎn)進(jìn)行第二步檢查.
下面以一棵5階B樹(shù)的插入操作舉例:
1. 首先插入39, 22, 97, 41:
2.? 插入39, 節(jié)點(diǎn)總key數(shù)量達(dá)到了5, 進(jìn)行分裂:
3.? 插入13, 21:
4. 插入40, 節(jié)點(diǎn)分裂, 22進(jìn)入父節(jié)點(diǎn):
5. 插入30, 27, 33, 其中33插入后, 該節(jié)點(diǎn)滿, 導(dǎo)致其分裂, 33進(jìn)入父節(jié)點(diǎn):
6. 插入36, 35, 34, 其中34插入后, 該節(jié)點(diǎn)滿, 導(dǎo)致節(jié)點(diǎn)分裂, 36進(jìn)入父節(jié)點(diǎn):
7. 插入24, 29:
8. 插入26, 導(dǎo)致該節(jié)點(diǎn)滿, 分裂, 27 進(jìn)入父節(jié)點(diǎn), 然后父節(jié)點(diǎn)也滿了, 再分裂, 創(chuàng)建新節(jié)點(diǎn):
3 刪除操作
1. 首先找到要?jiǎng)h除的點(diǎn), 如果點(diǎn)不在樹(shù)中, 那么肯定刪除失敗了.
2. 如果要?jiǎng)h除的節(jié)點(diǎn)位于葉子節(jié)點(diǎn), 那么拿掉這個(gè)節(jié)點(diǎn), 如果位于非葉子節(jié)點(diǎn)上, 那么就要找到其后繼節(jié)點(diǎn), 因?yàn)楹罄^節(jié)點(diǎn)肯定位于葉子節(jié)點(diǎn)上(因?yàn)榭隙ㄎ挥谧钭? 如果還位于非葉上面, 因其左子節(jié)點(diǎn)肯定存在比其大的節(jié)點(diǎn), 不可能出現(xiàn)這種情況), 把要?jiǎng)h除的節(jié)點(diǎn)替換成后繼節(jié)點(diǎn)的值, 然后刪除后繼節(jié)點(diǎn).
3. 因?yàn)樽罱K刪除的點(diǎn)位于葉子上, 所以要觀察此時(shí)該葉節(jié)點(diǎn)是否滿足B樹(shù)的性質(zhì)3:
非根節(jié)點(diǎn)至少有k個(gè)關(guān)鍵字, 這里的k是指ceil(M / 2) - 1
如果滿足, 那么結(jié)束刪除操作, 如果不滿足, 那么進(jìn)行4.
4. 先觀察兄弟節(jié)點(diǎn)的情況:
如果兄弟節(jié)點(diǎn)的key數(shù)量大于k, 那么把父親節(jié)點(diǎn)的key下移至該節(jié)點(diǎn), 并把兄弟節(jié)點(diǎn)的一個(gè)節(jié)點(diǎn)上移至父節(jié)點(diǎn)
否則, 將父節(jié)點(diǎn)中的key下移與當(dāng)前節(jié)點(diǎn)及其兄弟節(jié)點(diǎn)中的key合并, 形成一個(gè)新的節(jié)點(diǎn). 原父節(jié)點(diǎn)中的key的兩個(gè)孩子指針就變成了一個(gè)孩子指針, 指向這個(gè)新節(jié)點(diǎn), 然后當(dāng)前節(jié)點(diǎn)的指針指向父節(jié)點(diǎn), 重復(fù)第3步.
舉例說(shuō)明:
1. 原始狀態(tài)5階B樹(shù), 每個(gè)非根節(jié)點(diǎn)的最少關(guān)鍵字?jǐn)?shù)量為ceil(5 / 2) - 1 = 2:
2. 刪除21, 位于葉節(jié)點(diǎn), 且刪除完成后該節(jié)點(diǎn)關(guān)鍵字?jǐn)?shù)量為2, 結(jié)束:
3. 刪除27, 27位于非葉子節(jié)點(diǎn)上
3.1 首先把其值修改為后繼節(jié)點(diǎn)28:
3.2?刪除28, 28位于葉子節(jié)點(diǎn)上, 刪去:
3.3 此時(shí)該節(jié)點(diǎn)key數(shù)量小于2, 其左邊的兄弟節(jié)點(diǎn)有三個(gè)key, 可以把父節(jié)點(diǎn)一個(gè)key移下來(lái), 把兄弟節(jié)點(diǎn)一個(gè)key移到父節(jié)點(diǎn), 具體操作就是把28下移, 26上移, 完成:
4.?刪除32
4.1 首先刪除32:
4.2 該節(jié)點(diǎn)key數(shù)量為1, 小于2, 而兄弟節(jié)點(diǎn)也沒(méi)有大于2的了, 所以讓父節(jié)點(diǎn)中對(duì)應(yīng)的key30下移與該節(jié)點(diǎn)和兄弟節(jié)點(diǎn)合并:
總結(jié)
以上是生活随笔為你收集整理的多路平衡查找树 --- B(B-)树的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: python基础文档_python基本文
- 下一篇: xxljob 配置文件_最详细的xxl-