1. 程式人生 > >B數與B+數

B數與B+數

B樹

為什麼要B樹

磁碟中有兩個機械運動的部分,分別是碟片旋轉和磁臂移動。碟片旋轉就是我們市面上所提到的多少轉每分鐘,而磁碟移動則是在碟片旋轉到指定位置以後,移動磁臂後開始進行資料的讀寫。那麼這就存在一個定位到磁碟中的塊的過程,而定位是磁碟的存取中花費時間比較大的一塊,畢竟機械運動花費的時候要遠遠大於電子運動的時間。當大規模資料儲存到磁碟中的時候,顯然定位是一個非常花費時間的過程,但是我們可以通過B樹進行優化,提高磁碟讀取時定位的效率。

簡介

這裡的B樹,也就是英文中的B-Tree,一個 m 階的B樹滿足以下條件:

  1. 每個結點至多擁有m棵子樹;
  2. 除了根結點以外,其餘每個分支結點至少擁有 m/2 棵子樹;
  3. 根結點至少擁有兩顆子樹(存在子樹的情況下);
  4. 所有的葉結點都在同一層上,其可以看作是外部結點,不包含任何資訊;
  5. 有 k 棵子樹的非葉子結點則其存在 k-1 個關鍵碼,關鍵碼按照遞增次序進行排列;
  6. 關鍵字數量需要滿足ceil(m/2)-1 <= n <= m-1;

舉個栗子:

B樹上大部分的操作所需要的磁碟存取次數和B樹的高度是成正比的,在B樹中可以檢查多個子結點,由於在一棵樹中檢查任意一個結點都需要一次磁碟訪問,所以B樹避免了大量的磁碟訪問。

操作

既然是樹,那麼必不可少的操作就是插入和刪除,這也是B樹和其它資料結構不同的地方,當然了,還有必不可少的搜尋,分享一個對B樹的操作進行視覺化的

網址,它是由usfca提供的。

假定對高度為h的m階B樹進行操作。

插入

新結點一般插在第h層,通過搜尋找到對應的結點進行插入,那麼根據即將插入的結點的數量又分為下面幾種情況。

  • 如果該結點的關鍵字個數沒有到達m-1個,那麼直接插入即可;
  • 如果該結點的關鍵字個數已經到達了m-1個,那麼根據B樹的性質顯然無法滿足,需要將其進行分裂。分裂的規則是該結點分成兩半,將中間的關鍵字進行提升,加入到父親結點中,但是這又可能存在父親結點也滿員的情況,則不得不向上進行回溯,甚至是要對根結點進行分裂,那麼整棵樹都加了一層。

其過程如下:

刪除

同樣的,我們需要先通過搜尋找到相應的值,存在則進行刪除,需要考慮刪除以後的情況,

  • 如果該結點擁有關鍵字數量仍然滿足B樹性質,則不做任何處理;
  • 如果該結點在刪除關鍵字以後不滿足B樹的性質(關鍵字沒有到達ceil(m/2)-1的數量),則需要向兄弟結點借關鍵字,這有分為兄弟結點的關鍵字數量是否足夠的情況。
    • 如果兄弟結點的關鍵字足夠借給該結點,則過程為將父親結點的關鍵字下移,兄弟結點的關鍵字上移;
    • 如果兄弟結點的關鍵字在借出去以後也無法滿足情況,即之前兄弟結點的關鍵字的數量為ceil(m/2)-1,借的一方的關鍵字數量為ceil(m/2)-2的情況,那麼我們可以將該結點合併到兄弟結點中,合併之後的子結點數量少了一個,則需要將父親結點的關鍵字下放,如果父親結點不滿足性質,則向上回溯;
  • 其餘情況參照BST中的刪除。

其過程如下:

B+樹

為什麼要B+樹

由於B+樹的資料都儲存在葉子結點中,分支結點均為索引,方便掃庫,只需要掃一遍葉子結點即可,但是B樹因為其分支結點同樣儲存著資料,我們要找到具體的資料,需要進行一次中序遍歷按序來掃,所以B+樹更加適合在區間查詢的情況,所以通常B+樹用於資料庫索引,而B樹則常用於檔案索引。

簡介

同樣的,以一個m階樹為例:

  1. 根結點只有一個,分支數量範圍為[2,m];
  2. 分支結點,每個結點包含分支數範圍為[ceil(m/2), m];
  3. 分支結點的關鍵字數量等於其子分支的數量;
  4. 所有葉子結點都在同一層,其關鍵字的數量範圍為[ceil(m/2), m],從小到達進行排序;

操作

其操作和B樹的操作是類似的,不過需要注意的是,在增加值的時候,如果存在滿員的情況,將選擇結點中的值作為新的索引,還有在刪除值的時候,索引中的關鍵字並不會刪除,也不會存在父親結點的關鍵字下沉的情況,因為那只是索引。

B樹和B+樹的區別

這都是由於B+樹和B具有這不同的儲存結構所造成的區別,以一個m階樹為例。

  1. 關鍵字的數量不同;B+樹中分支結點有m個關鍵字,其葉子結點也有m個,其關鍵字只是起到了一個索引的作用,但是B樹雖然也有m個子結點,但是其只擁有m-1個關鍵字。
  2. 儲存的位置不同;B+樹中的資料都儲存在葉子結點上,也就是其所有葉子結點的資料組合起來就是完整的資料,但是B樹的資料儲存在每一個結點中,並不僅僅儲存在葉子結點上。
  3. 分支結點的構造不同;B+樹的分支結點僅僅儲存著關鍵字資訊和兒子的指標(這裡的指標指的是磁碟塊的偏移量),也就是說內部結點僅僅包含著索引資訊。
  4. 查詢不同;B樹在找到具體的數值以後,則結束,而B+樹則需要通過索引找到葉子結點中的資料才結束,也就是說B+樹的搜尋過程中走了一條從根結點到葉子結點的路徑。