B樹和B+樹總結
B樹
簡介
這里的B樹,也就是英文中的B-Tree,一個 m 階的B樹滿足以下條件:
每個結點至多擁有m棵子樹;
根結點至少擁有兩顆子樹(存在子樹的情況下),根結點至少有一個關鍵字;
除了根結點以外,其余每個分支結點至少擁有 m/2 棵子樹;
所有的葉結點都在同一層上,B樹的葉子結點可以看成是一種外部節點,不包含任何信息;
有 k 棵子樹的分支結點則存在 k-1 個關鍵碼,關鍵碼按照遞增次序進行排列;
關鍵字數量需要滿足ceil(m/2)-1 <= n <= m-1;
舉個栗子:
為什么要B樹
磁盤中有兩個機械運動的部分,分別是盤片旋轉和磁臂移動。盤片旋轉就是我們市面上所提到的多少轉每分鍾,而磁盤移動則是在盤片旋轉到指定位置以后,移動磁臂后開始進行數據的讀寫。那么這就存在一個定位到磁盤中的塊的過程,而定位是磁盤的存取中花費時間比較大的一塊,畢竟機械運動花費的時候要遠遠大於電子運動的時間。當大規模數據存儲到磁盤中的時候,顯然定位是一個非常花費時間的過程,但是我們可以通過B樹進行優化,提高磁盤讀取時定位的效率。
為什么B類樹可以進行優化呢?我們可以根據B類樹的特點,構造一個多階的B類樹,然后在盡量多的在結點上存儲相關的信息,保證層數盡量的少,在B樹中可以檢查多個子結點,由於在一棵樹中檢查任意一個結點都需要一次磁盤訪問,所以B樹避免了大量的磁盤訪問;而且B類樹是平衡樹,每個結點到葉子結點的高度都是相同,這也保證了每個查詢是穩定的,查詢的時間復雜度是O(log2N)。
總的來說就是利用平衡樹的優勢,保證了查詢的穩定性和加快了查詢的速度。
操作
既然是樹,那么必不可少的操作就是插入和刪除,這也是B樹和其它數據結構不同的地方,當然了,還有必不可少的搜索,分享一個對B樹的操作進行可視化的網址,它是由usfca提供的。
假定對高度為h的m階B樹進行操作。
插入
通過搜索找到對應的結點進行插入,那么根據即將插入的結點的數量又分為下面幾種情況。
如果該結點的關鍵字個數沒有到達到m-1個,那么直接插入即可;
如果該結點的關鍵字個數已經到達了m-1個,那么根據B樹的性質顯然無法滿足,需要將其進行分裂。分裂的規則是該結點分成兩半,將中間的關鍵字進行提升,加入到父親結點中,但是這又可能存在父親結點也滿員的情況,則不得不向上進行回溯,甚至是要對根結點進行分裂,那么整棵樹都加了一層。
其過程如下:
刪除
同樣的,我們需要先通過搜索找到相應的值,存在則進行刪除,需要考慮刪除以后的情況,
如果該結點擁有的關鍵字數量仍然滿足B樹性質,則不做任何處理;
如果該結點在刪除關鍵字以后不滿足B樹的性質(關鍵字沒有到達ceil(m/2)-1的數量),則需要向兄弟結點借關鍵字,這又分為兄弟結點的關鍵字數量是否足夠的情況。
如果兄弟結點的關鍵字足夠借給該結點,則將父親結點的關鍵字下移,兄弟結點的關鍵字上移;
如果兄弟結點的關鍵字在借出去以后也無法滿足B樹性質,即之前兄弟結點的關鍵字的數量為ceil(m/2)-1,借的一方的關鍵字數量為ceil(m/2)-2的情況,那么我們可以將該結點合並到兄弟結點中,合並之后的子結點數量少了一個,則需要將父親結點的關鍵字下放,如果父親結點不滿足性質,則向上回溯;
其余情況參照BST中的刪除。
其過程如下:
B+樹
簡介
B+樹是B樹的變形體,性質和B樹一致;
如圖
操作
其操作和B樹的操作是類似的,不過需要注意的是,在增加值的時候,如果存在滿員的情況,將選擇結點中的值作為新的索引,還有在刪除值的時候,索引中的關鍵字並不會刪除,也不會存在父親結點的關鍵字下沉的情況,因為那只是索引。
B樹和B+樹的區別
這都是由於B+樹和B樹具有不同的存儲結構所造成的區別,以一個m階樹為例。
關鍵字的數量不同;B+樹中分支結點有m個關鍵字,其葉子結點也有m個,其關鍵字只是起到了一個索引的作用,雖然B樹也有m個子結點,但是其只擁有m-1個關鍵字。
存儲的位置不同;B+樹中的數據都存儲在葉子結點上,也就是其所有葉子結點的數據組合起來就是完整的數據,但是B樹的數據存儲在每一個結點中,並不僅僅存儲在葉子結點上。
分支結點的構造不同;B+樹的分支結點存儲着關鍵字信息和兒子的指針(這里的指針指的是磁盤塊的偏移量),也就是說內部結點僅僅包含着索引信息。
查詢不同;B樹在找到具體的數值以后就結束,而B+樹則需要通過索引找到葉子結點中的數據才結束,也就是說B+樹的搜索過程中走了一條從根結點到葉子結點的路徑,其高度是相同的,相對來說更加的穩定;
區間訪問:B+樹的葉子結點會按照順序建立起鏈狀指針,可以進行區間訪問;