1. 程式人生 > >面試總結:B樹,B+樹的原理及區別

面試總結:B樹,B+樹的原理及區別

之前在網上看到過一些B樹與B+樹的區別然後主要是針對定義來陳述,分分鐘看的我快要冬眠,然後在一次面試遇到該沒問題沒回答上來一首涼涼送 給自己,今天老老實實的分享自己對B樹,B+樹淺顯理解,若望指出不足。

B樹的原理

動態查詢樹主要包括:二叉搜尋樹,平衡二叉樹,紅黑樹,B樹,B-樹時間複雜度O(log2N),通過對樹高度的降低可以提升查詢效率

尤其是在大量資料進行儲存的時候會儲存到外部 磁碟,通過對外部磁碟的讀取時需要快速的查詢到對應的位置,所以需要一種高效的外村資料結構。

B樹:就是為了儲存裝置或者磁碟設計的一種平衡查詢樹

辨析1:B樹與紅黑樹的區別

B樹的節點可以有很多孩子節點,紅黑樹是一種近似平衡的二叉搜尋樹即每個節點只有兩個孩子
一顆含有N個節點的B樹和紅黑樹的高度是一樣的O(lgn)。
圖片來自百度百科


B樹的定義
對於一顆M階的B樹

1)樹中的每個節點最多有m個孩子
2)除了根節點和葉子節點外,其他節點最少含有m/2(取上限)個孩子
3)若根節點不是葉子節點,則根節點最少含有兩個孩子
4)所以葉子節點都在同一層,葉子節點不包含任何關鍵字資訊
B樹的型別與節點定義
struct BTNode
{
	int keyNum ; //實際關鍵字的個數
	PBTNode parent;//指向父親節點
	PBTNode *ptr ;
	keyType *key ; //關鍵字向量
}

B樹的插入操作/

B樹的插入
1)若B樹中已存在需要插入的鍵值時,用新的鍵值替換舊值;
2)若B樹中不存在這個值,則在葉子節點進行插入操作;
具體插入過程如下

對於高度為h的m階B樹,新節點一般插在第h層。	
1)若該節點中關鍵碼個數小於m-1,則直接插入
2)若該節點中關鍵碼個數等於m-1,則節點分裂。以中間的關鍵碼為界,
	將節點一分為二,產生一個新的節點,並將中間關鍵碼插入到父節點中。
重複上述過程,最壞情況一直分裂高根節點,則B樹就會增加一層。

一般B樹用來新增以便查詢,這裡沒有對刪除做出理解,有興趣可參考連結
參考如下(含有插入,刪除的圖解過程)
https://www.cnblogs.com/guohai-stronger/p/9225057.html

B+樹的原理

B+樹特點

1)B+樹是B樹的一種變形,它把資料都儲存在葉子節點,內部只存關鍵字(其中葉子節點的最小值作為索引)和孩子指標,簡化了內部節點。
2)B+樹的遍歷高效,將所以葉子節點串聯成連結串列即可從頭到尾遍歷,

B+樹的定義

1)有n棵子樹的結點含有n個關鍵字,每個關鍵字都不儲存資料,
	只用來索引,並且所有的資料都儲存在葉子節點
2)所有葉子結點包含所有關鍵字資訊和指向關鍵字記錄的指標,
其中關鍵字從小到大順序連結

在這裡插入圖片描述

B+樹的插入操作

B+樹插入:
1)若為空樹直接插入
2)對於葉子結點:根據key找到葉子結點,對葉子結點進行插入操作。插入後如果當前葉子結點的key值數b不大於m-1,則插入結束。

反之,將這個葉子結點分成左右兩個葉子結點進行操作,
左葉子結點包含前m/2個記錄,右葉子結點包含剩下的記錄key,
將第m/2+1個記錄的key進位到父結點中,(父結點必須是索引型別的結點)
進位到父結點的key,進位的key左孩子指向左結點,右孩子指向右結點。

3)對於索引結點:如果當前結點的key個數小於等於m-1,插入結束。

反之,將這個索引型別的結點分成兩個索引結點,
左索引結點包含前(m-1)/2個數據,右結點包含m-(m-1)/2個數據
將第m/2個key進位到父結點中,進位的key左孩子指向左結點,右孩子指向右結點

插入圖解參考原文
https://www.cnblogs.com/guohai-stronger/p/9225057.html

剖析2:為什麼B+樹比B樹更適合做系統的資料庫索引和檔案索引
1)B+樹的磁碟讀寫代價更低
因為B+樹內部結點沒有指向關鍵字具體資訊的指標,內部結點相對B樹小
2)B+樹的查詢更加穩定
因為非終端結點並不是指向檔案內容的結點,僅僅是作為葉子結點的關鍵字索引,因此所有的關鍵字查詢都會走一條從根節點到葉子結點的路徑。即s所有關鍵字查詢的長度是一樣的,查詢效率穩定。

今日份分享告一段落。

B樹的程式碼實現參考原文
https://www.cnblogs.com/guohai-stronger/p/9225057.html