一顆m階的b樹,這裡階的意思是指每個節點擁有的子節點個數,會滿足以下幾點:
(1)每個節點最多有m個子節點
(2)除了根節點和葉子節點之外,其它的每個節點最少有m/
2(向上取整)個子節點
(3)根節點至少有兩個子節點,(除了第一次插入的時候,此時只有乙個節點,根節點同時是葉子節點)
(4)所有的葉子節點都在同一層
(5)有k個子節點的父節點包含k-
1個key關鍵字
初次接觸b樹的時候有兩個問題比較疑惑,根節點為什麼最少要有兩個子節點?其它的節點為什麼又是最少有m/2個子節點?直到看到這篇部落格之後茅塞頓開。簡單來講b樹的上述幾個條件就是為了維持樹的平衡。
下面舉個例子來說明一下,所有的都是來自於data structure visualization**,可以保證的正確性。
我們依次往一顆b樹裡邊插入遞增的數字來觀察樹形狀的變化。
第乙個例子,m=3,一顆三階的b樹,依次插入1,2,3。
當3這個key插入的時候,首先試圖插入根節點,但是此時根節點總共有4個子節點(下圖4個指向子節點的childptr),不滿足條件1,即子節點數量不能超過3,於是根節點要**。
根節點一分為三,**之後是這樣的:
**的時候,中間的以中間的key-2為中心,將keys分成三份,中間的key作為新的根節點;左邊的部分作為新根節點的左子樹,同樣的道理右邊的部分作為右子樹。
也就是說中間的key成為根節點後,至少兩個子節點,這就是條件3,這就是根節點為什麼至少兩個子節點的原因。
我們繼續往b樹新增key。
當5加進去的時候,最右邊葉子節點不滿足條件,**。
加入6
當7進去的時候,會導致最右邊的葉子節點不滿足要求,於是葉子節點右開始**
當key(6)上移到它的父節點之後又會導致父節點不滿足要求,繼續**。
最後的b樹如下,此時樹的高度變為了3.
可以這麼理解,隨著資料的不斷加入,樹的高度就會慢慢變高,b樹的層數增加是通過**根節點完成的。
當根節點要**的時候,為什麼是**成左右兩個子樹而不能**成超過兩個子樹呢?這是由於條件2:除了根節點和葉子節點之外,其它的每個節點最少有m/2(向上取整)個子節點。如果分成三個子節點,那麼每個子節點的包含的節點數就是m/3,不滿足條件2。
再舉乙個例子
下面再建個7階的b樹,依次加入1,2,3,4,5,6,7。
當7加入的時候,根節點共有8個child指標,不滿足條件1,所以要**,這種情況就以中間的key(4)作為新的根節點,1,2,3作為新的根節點的左子節點,5,6,7作為右子節點。變成這個樣子:
第三個例子,這個例子其實重複了,只是多舉點例子加深理解
下圖是根節點第二次**的情況,這是一顆5階b樹,儲存1到16的key,目前高度為2
當我們往這顆b樹加入17的時候,最右邊的葉子有6個childptr,不滿足條件1。所以這個節點也要執行**,的中間的key(15)要上移到父節點,同時**為兩個節點,此時它的父節點就是根節點。但是**之後就會導致根節點不滿足要求,此時根節點有6個子節點。
由於根節點不滿足要求,所以根節點也要執行**操作。
還是以中間的key作為新的根節點,左右兩邊分別作為左右子樹,變成這個樣子:
這時候新的根節點還是兩個子樹,通過上面的幾個例子很容易理解根節點為什麼最少要有兩個子節點
為什麼MySQL使用B 樹?
首先需要理解磁碟io的原理 硬碟中一般會有多個碟片組成,每個碟片包含兩個面,每個盤面都對應地有乙個讀 寫磁頭。將磁軌劃分為若干個弧段,每個磁軌上乙個弧段被稱之為乙個扇區 圖踐綠色部分 扇區是磁碟的最小組成單元。硬碟通常由重疊的一組碟片構成,每個盤面都被劃分為數目相等的磁軌,並從外緣的 0 開始編號,...
MySQL為什麼用B 樹,而不用B樹?
面試題1 mysql為什麼用b 樹,而不用b樹?1.b 樹只有葉子節點存資料 b樹是每個節點都存資料 在相同資料量下b樹的高度更高,所以查詢效率更低 2.b樹每一層存的是資料 索引 b 樹是除了葉子節點存的是資料 索引以外,其餘節點只存索引,所以在相同資料量的情況下,b樹的高度會比b 樹高很多 面試...
為什麼Mysql用B 樹做索引而不用B 樹
先從資料結構的角度來答。題主應該知道b 樹和b 樹最重要的乙個區別就是b 樹只有葉節點存放資料,其餘節點用來索引,而b 樹是每個索引節點都會有data域。這就決定了b 樹更適合用來儲存外部資料,也就是所謂的磁碟資料。從mysql inoodb 的角度來看,b 樹是用來充當索引的,一般來說索引非常大,...