Day16

多路搜索樹
以k層爲間隔,將二叉搜索樹的各結點及其孩子(和孫子)合併爲含有2(k)-1個關鍵碼,2(k)個分支的“大結點”,得到2(k)路搜索樹,統稱多路搜索樹。
四路搜索樹

m階B-樹:m路平衡搜索樹。所有外部節點深度相等,所有內部節點都有不超過m-1個關鍵碼,以及用以指示其對應分支的不超過m個引用。
即,存有n<=m-1個關鍵碼的內部節點同時配有n+1<=m個引用,除根以外的所有內部結點都應滿足 n+1 >= ceiling(m/2),在非空的B-樹中,根節點應該滿足 n+1 >= 2。
由於各結點的分支數在ceiling(m/2)到m之間,所以m階B-樹又稱爲(ceiling(m/2), m)-樹。
在計算B-樹高度的時候需要計入其底部的外部結點。
但通常爲了表示方便會在圖中省略外部結點。
B-樹最緊湊表示方式

查找:
與二叉搜索樹過程基本相似。以根節點作爲當前結點逐層深入,如果在當前節點所包含的一組關鍵碼中能找到目標關鍵碼,則成功返回,如果當前結點的關鍵碼中不存在目標,則必可在當前節點中確定某一個引用,並通過該引用轉至邏輯上處於下一層的另一節點,如果這個結點不是外部結點,則將其載入內存,並更新爲當前結點,重複上述過程。

對於高度爲h的B-樹,其查找過程中對外存的訪問不超過O(h-1)次。
對於一共有N個關鍵碼的m階B-樹的高度h,必有:
這裏寫圖片描述

對有N個關鍵碼的m階B-樹,查找耗時不超過O(log(m)N).

插入:
與二叉搜索樹過程相似,不過,在最後的葉子結點上插入後,如果該葉子結點內關鍵碼個數依然小於m-1,才爲插入成功,否則稱該結點發生了一次上溢。
處理上溢:
一般上溢的結點恰好有m個關鍵碼,所以對於s = floor(m/2),以關鍵碼ks爲界限恰好能分成等長的兩部分,於是可讓關鍵碼ks升入上一層,歸入其父結點的適當位置,並分別以剛纔分開的兩個結點作爲其左右孩子,這一過程也稱作節點分裂。
這個過程中分爲三種情況:
1.如果上溢結點的父結點不爲空,且該父結點未飽和,則將ks升到父節點中後,修復成功,過程結束;
2.如果上溢結點的父結點不爲空,但該父結點已經飽和,則不斷重複這一調整過程,直至根節點。
3.如果上溢傳遞到了根節點,根節點也飽和了,則將k’s升爲新的根節點,樹高度+1.

刪除:
與二叉搜索樹刪除過程類似,先搜索,如果找到目標則將目標與其右子樹中最小的那個葉節點互換,然後刪除。如果刪除目標後其所在的葉結點的關鍵碼個數不小於ceiling(m/2) - 1,則稱刪除成功,否則成爲發生下溢。
處理下溢:
在剛發生下溢的m階B-樹中,下溢結點V的關鍵碼個數肯定爲ceiling(m/2) - 2,且包含ceiling(m/2) -1個分支,同樣分爲3種情況處理。
1. 如果V的左兄弟L存在,且L至少包含ceiling(m/2)個關鍵碼,則取L中最大的關鍵碼x,以及V和L的父結點P的關鍵碼y,將x升爲父結點P的關鍵碼,而將y降爲V的關鍵碼。
2. 如果V的右兄弟R存在,且R至少包含ceiling(m/2)個關鍵碼,則取R中最小的關鍵碼x,以及V和R的父結點P的關鍵碼y,將x升爲父結點P的關鍵碼,而將y降爲V的關鍵碼。
3. 如果V的左右兄弟都不存在(這種情況下不可能同時不存在,所以只考慮後一種情況),或者左右兄弟的關鍵碼個數也恰好爲ceiling(m/2)-1,則假設V的左兄弟L(右兄弟R)存在,取V和L(R)的父結點P的關鍵碼y,將y從父結點取出,作爲連接V和L(R)的關鍵碼,形成一個新的結點,這一過程也成爲結點的合併。
此時合併後的新節點的關鍵碼個數爲
ceiling(m/2)-1+1+ceiling(m/2)-2 = 2*ceiling(m/2)-2 <= m-1
所以此時也不會發生上溢。
如果處理完V,其父結點由於刪除了y也發生了下溢,則不斷重複上訴步驟直到沒有結點下溢,或下溢傳遞到了根節點,如果下溢傳遞到了根節點,且根節點中沒有關鍵碼時,可直接將根節點刪除,以其子結點作爲新的根節點。
整個過程中最多需要做O(log(m)N)次合併操作。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章