Java架構直通車——深入理解B+樹

引入:AVL樹和B樹

AVL樹

平衡二叉搜索樹是基於二分法的策略提高數據的查找速度的二叉樹的數據結構;平衡二叉搜索樹的數據結構組裝過程有以下規則:
(1)非葉子節點只能允許最多兩個子節點存在。
(2)每一個非葉子節點數據分佈規則爲左邊的子節點小當前節點的值,右邊的子節點大於當前節點的值(這裏值是基於自己的算法規則而定的,比如hash值);

在這裏插入圖片描述

平衡樹的層級結構:因爲平衡二叉樹查詢性能和樹的層級(h高度)成反比,h值越小查詢越快、爲了保證樹的結構左右兩端數據大致平衡降低二叉樹的查詢難度一般會採用一種算法機制實現節點數據結構的平衡,實現了這種算法的有比如紅黑樹,使用平衡二叉樹能保證數據的左右兩邊的節點層級相差不會大於1.,通過這樣避免樹形結構由於刪除增加變成線性鏈表影響查詢效率,保證數據平衡的情況下查找數據的速度近於二分法查找。

紅黑樹

紅黑樹是一種含有紅黑結點並能自平衡的二叉查找樹。它必須滿足下面性質:

性質1:每個節點要麼是黑色,要麼是紅色。
性質2:根節點是黑色。
性質3:每個葉子節點(NIL)是黑色。
性質4:每個紅色結點的兩個子結點一定都是黑色。
性質5:任意一結點到每個葉子結點的路徑都包含數量相同的黑結點。

從性質5又可以推出:
性質5.1:如果一個結點存在黑子結點,那麼該結點肯定有兩個子結點

在這裏插入圖片描述
紅黑樹並不是一個完美平衡二叉查找樹,從圖1可以看到,根結點P的左子樹顯然比右子樹高,但左子樹和右子樹的黑結點的層數是相等的,也即任意一個結點到到每個葉子結點的路徑都包含數量相同的黑結點(性質5)。所以我們叫紅黑樹這種平衡爲黑色完美平衡。

紅黑樹能夠以O(log2(N))的時間複雜度進行搜索、插入、刪除操作,具體操作方法參考30張圖帶你徹底理解紅黑樹🔗。此外,任何不平衡都會在3次旋轉之內解決。這一點是AVL所不具備的。

B樹(B-樹)

B樹和平衡二叉樹稍有不同的是B樹屬於多叉樹又名平衡多路查找樹(查找路徑不只兩個)。B樹的每個節點最多包含m個孩子,m稱爲b樹的階。

一個M階的b樹具有如下幾個特徵:

  • 定義任意非葉子結點最多隻有M個兒子,且M>2;
  • 根結點的兒子數爲[2, M];
  • 除根結點以外的非葉子結點的兒子數爲[M/2, M],向上取整;
  • 非葉子結點的關鍵字個數=兒子數-1;
  • 所有葉子結點位於同一層;
  • k個關鍵字把節點拆成k+1段,分別指向k+1個兒子,同時滿足查找樹的大小關係。

在這裏插入圖片描述

  • B樹的查詢流程:

如上圖我要從上圖中找到E字母,查找流程如下

(1)獲取根節點的關鍵字進行比較,當前根節點關鍵字爲M,E<M(26個字母順序),所以往找到指向左邊的子節點(二分法規則,左小右大,左邊放小於當前節點值的子節點、右邊放大於當前節點值的子節點);

(2)拿到關鍵字D和G,D<E<G 所以直接找到D和G中間的節點;

(3)拿到E和F,因爲E=E 所以直接返回關鍵字和指針信息(如果樹結構裏面沒有包含所要查找的節點則返回null);

  • B樹的插入節點流程:

定義一個5階樹(平衡5路查找樹;),現在我們要把3、8、31、11、23、29、50、28 這些數字構建出一個5階樹出來;

遵循規則:

(1)節點拆分規則:當前是要組成一個5路查找樹,那麼此時m=5,關鍵字數必須<=5-1(這裏關鍵字數>4就要進行節點拆分);

(2)排序規則:滿足節點本身比左邊節點大,比右邊節點小的排序規則;

先插入 3、8、31、11
在這裏插入圖片描述

再插入23、29

在這裏插入圖片描述
再插入50、28
在這裏插入圖片描述

  • B樹節點的刪除

規則:

(1)節點合併規則:當前是要組成一個5路查找樹,那麼此時m=5,關鍵字數必須大於等於ceil(5/2)(這裏關鍵字數<2就要進行節點合併);

(2)滿足節點本身比左邊節點大,比右邊節點小的排序規則;

(3)關鍵字數小於二時先從子節點取,子節點沒有符合條件時就向向父節點取,取中間值往父節點放;

在這裏插入圖片描述

數據庫爲什麼不使用二叉樹?

局部性原理與磁盤預讀

由於存儲介質的特性,磁盤本身存取就比主存慢很多,再加上機械運動耗費,磁盤的存取速度往往是主存的幾百分分之一,因此爲了提高效率,要儘量減少磁盤I/O。爲了達到這個目的,磁盤往往不是嚴格按需讀取,而是每次都會預讀,即使只需要一個字節,磁盤也會從這個位置開始,順序向後讀取一定長度的數據放入內存。這樣做的理論依據是計算機科學中著名的局部性原理:當一個數據被用到時,其附近的數據也通常會馬上被使用。程序運行期間所需要的數據通常比較集中

由於磁盤順序讀取的效率很高(不需要尋道時間,只需很少的旋轉時間),因此對於具有局部性的程序來說,預讀可以提高I/O效率。預讀的長度一般爲頁(page)的整倍數。

數據庫系統的設計者巧妙利用了磁盤預讀原理,將一個節點的大小設爲等於一個頁,這樣每個節點只需要一次I/O就可以完全載入

所以我們要減少IO次數,對於樹來說,IO次數就是樹的高度,而“矮胖”就是b樹的特徵之一,它的每個節點最多包含m個孩子,m稱爲b樹的階,m的大小取決於磁盤頁的大小。(每次新建節點時,直接申請一個頁的空間,這樣就保證一個節點物理上也存儲在一個頁裏,加之計算機存儲分配都是按頁對齊的,就實現了一個node只需一次I/O。)

爲什麼使用B+樹(與B樹的區別)

B+樹是B樹的一個升級版,相對於B樹來說B+樹更充分的利用了節點的空間,讓查詢速度更加穩定,其速度完全接近於二分法查找。

規則

(1)B+跟B樹不同B+樹的非葉子節點不保存關鍵字記錄的指針,只進行數據索引,這樣使得B+樹每個非葉子節點所能保存的關鍵字大大增加;

(2)B+樹葉子節點保存了父節點的所有關鍵字記錄的指針,所有數據地址必須要到葉子節點才能獲取到。所以每次數據查詢的次數都一樣

(3)B+樹葉子節點的關鍵字從小到大有序排列,左邊結尾數據都會保存右邊節點開始數據的指針

在這裏插入圖片描述
特點
1、B+樹的層級更少
b+樹的中間節點不保存數據,所以磁盤頁能容納更多節點元素,更“矮胖”,查詢速度也就更快。

2、B+樹查詢速度更穩定:
B+所有關鍵字數據地址都存在葉子節點上,所以每次查找的次數都相同所以查詢速度要比B樹更穩定;

3、B+樹天然具備排序功能:
B+樹所有的葉子節點數據構成了一個有序鏈表,在查詢大小區間的數據時候更方便,數據緊密性很高,緩存的命中率也會比B樹高。

4、B+樹全節點遍歷更快:
B+樹遍歷整棵樹只需要遍歷所有的葉子節點即可,而不需要像B樹一樣需要對每一層進行遍歷,這有利於數據庫做全表掃描。
另外對於範圍查找來說,b+樹只需向後遍歷葉子節點鏈表即可。

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