我所知道數據結構之多路查找樹:2-3樹、B樹、B+樹、B*樹

前言需求算法


咱們上一篇文章中介紹了平衡二叉樹,以及爲何會有平衡二叉樹?sql

但其實二叉樹的操做效率較高,其實也是存在一些問題的數據庫

image.png

咱們通常二叉樹加載存放到內存中構建成,假如節點比較多(億:單位)性能

1.構建二叉樹時,須要屢次進行I/O 操做(海量數據存在數據庫/文件中),速度有影響
2.節點海量,會形成二叉樹高度很大,下降操做速度學習

這時咱們就提出一種樹想解決這個問題:多叉樹優化

1、什麼是多叉樹

基本介紹

1.在二叉樹中,每一個節點有數據項,最多有兩個子節點。若是容許每一個節點有更多數據項和更多的子節點,就是多叉樹(multiway Tree)spa

2.多叉樹經過從新組織節點,減小樹的高度,對二叉樹進行優化設計

(示例圖:2-3樹、2-3-4樹就是多叉樹)3d

image.png

2、什麼是2-3樹?

2-3樹的基本介紹

2-3樹便是最簡單的B樹結構,具備如下特色:指針

一、全部葉子節點都在同一層(B樹都知足這個條件)
二、有一個元素項且有兩個子節點叫二節點、二節點要麼有兩個子節點、要麼就沒子節點
三、有二個元素項且有三個子節點叫三節點、三節點要麼有三個子節點、要麼就沒子節點
四、由二節點與三節點構成的成爲2-3樹

image.png

咱們發現三節點EJ、有AC、H、L 子節點
其中它們的關係是 AC < H < L,而AC的關係又是 A < C的

3、經過示例認識2-3樹

2-3樹的應用示例

數列{16, 24, 12, 32, 14, 26, 34, 10, 8, 28, 38, 20}構建成2-3樹, 並保證數據插入的大小順序。

圖解演示2-3樹插入思路

第一步:插入:16 放入後成爲二節點(二節點有一個元素項,兩個子節點)
image.png

第二步:插入:24 放入後成爲三節點(三節點有二個元素項,三個子節點)
image.png

第三步:插入:12 時按理說應該是插入16前面,可是插入16前行麼?

image.png

不行,由於放入後就不是三節點了,變成了三個元素項了,咱們須要拆

image.png

第四步:插入:32 比16節點還要大,因此咱們從右子節點開始找位置

image.png

從右子節點找位置,嘗試的從24 節點後邊去放,判斷是否知足三節點

image.png

第五步:插入:14 同理,比16節點小,因此從左子節點開始找位置

image.png

從左子節點找位置,嘗試的從12 節點後邊去放,判斷是否知足三節點
image.png

第六步:插入:26 比16節點還要大,因此咱們從右子節點開始找位置

image.png

按理說咱們應該是放入2四、32 中間的,可是能放嗎?

不行,放了就變成三個元素項了,而且也不能成爲2四、32的子節點,由於放了三節點就只有一個子節點了,也不符合要求(三節點要麼有三個子節點、要麼就沒子節點)

image.png

所以咱們只能往上拆,使插入26 節點也知足條件要求

image.png

第七步:插入:34 比26 大,因此咱們從右子節點開始找位置
image.png

從右子節點找位置,嘗試的從32 節點後邊去放,判斷是否知足三節點
image.png

第八步:插入:10 比16節點小,因此從左子節點開始找位置
image.png

按理說咱們應該是放入12 前邊的,可是能放嗎?

不行,放了就變成三個元素項了,而且也不能成爲十二、14的子節點,由於放了三節點就只有一個子節點了,也不符合要求(三節點要麼有三個子節點、要麼就沒子節點)

image.png

那麼按照以前的插入節點26的思路,咱們須要拆節點不是嘛?

image.png

可是此時並不知足B樹的特色:全部葉子節點都在同一層,因此咱們須要調整

image.png

第九步:插入:8 比16節點還要小,因此咱們從左子節點開始找位置

image.png

按理說咱們應該是放入12 前邊的,可是12 有子節點,再進行尋找

image.png

從左子節點找位置,嘗試的從10 節點前邊去放,判斷是否知足三節點

image.png

第十步:插入:28 比16節點大,因此咱們從右子節點開始找位置

image.png

按理說咱們應該是放入26 後邊的,可是26有子節點,再進行判斷尋找

image.png

按理說咱們應該是放入32 前邊的,可是能放嗎?

不行,放了就變成三個元素項了,而且也不能成爲3二、34的子節點,由於放了三節點就只有一個子節點了,也不符合要求(三節點要麼有三個子節點、要麼就沒子節點)

image.png

那麼按照以前的插入節點的思路,咱們須要拆節點不是嘛?

image.png

第十一步:插入:38 比16節點大,因此咱們從右子節點開始找位置

image.png

按理說咱們應該是放入2六、32 後邊的,可是放入後就變成三個元素項了,不過2六、32有子節點,再進行判斷尋找。

image.png

從右子節點找位置,嘗試的從34節點後邊去放,判斷是否知足三節點
image.png

第十二步:插入:20 比16節點大,因此咱們從右子節點開始找位置

image.png

按理說咱們應該是放入26,32 前邊的,可是放入後就變成三個元素項了,不過2六、32有子節點,再進行判斷尋找。

image.png

從左子節點找位置,嘗試的從20節點前邊去放,判斷是否知足三節點

image.png

4、什麼是B樹

B樹的基本介紹

咱們能夠看看B樹的這些節點圖來多多認識經過從新組織節點,減小樹的高度

image.png

1.如圖B樹經過經過從新組織節點,減小樹的高度

2.文件系統及數據庫的設計者利用磁盤預讀原理,將一個節點的大小設爲等於一個頁的大小(一般爲4k),這樣每一個節點只須要一次I/O 便可

3.將樹的度M設置爲1024,在600億個元素中最多隻須要4次I/O便可讀取想要的元素,普遍用於文件存儲系統以及數據庫系統中

(會不會有小夥伴提問:什麼是樹的度M?)

講樹的度M以前須要知道什麼是節點的度?

通常來講咱們都知道二叉樹最多有兩個子節點

假如A節點有B、C 兩子節點,咱們稱A節點的度爲2,即度爲子樹有幾個。

那麼樹的度呢?指全部節點的度裏的最大的值,即爲樹的度M

B樹的說明

咱們前面介紹的2-3樹、甚至2-3-4樹,它們也是屬於B樹,我能夠先看看以前咱們學習Mysql時,常常聽見某種類型的索引是基於B樹或者B+樹的原理是個什麼狀況呢?

image.png

咱們先說明B樹的幾個點:

第一點:B樹有一個概念叫:階,指的是節點的最多子節點個數,好比2-3樹階是3,2-3-4樹的階是4

第二點:B樹的搜索:從根節點開始,對節點內的關鍵字(有序)序列進行二分查找,若是命中則結束,不然進入查詢關鍵字所屬範圍的兒子節點,重複操做,直到所對應的兒子節點爲指針爲空或者已經是葉子節點

image.png

image.png

image.png

image.png

第三點:關鍵字集合分佈在整顆樹中,即葉子節點和非葉子節點都存放數據

第四點:搜索有可能在非葉子節點就結束

image.png

image.png

第五點:其搜索性能等價於在關鍵字全集內作一次二分查找

5、什麼是B+樹

B+樹的基本介紹

B+樹是B樹的變體,也是一種多路搜索樹

圖片.png

咱們說明B+樹與B樹的一些特色

第一點:B+樹的搜索與B樹也基本相同,區別是B+樹只有達到葉子節點纔會命中(B樹能夠在非葉子節點命中),性能也等價於作一次二分查找

第二點:全部關鍵字都出如今葉子節點的鏈表中(數據只能在葉子節點),這叫稠密索引且鏈表中的關鍵字剛好是有序的

圖片.png

第三點:非葉子節點至關因而葉子節點的索引(稀疏索引),葉子節點是存儲數據的數據層

圖片.png

第四點:不可能在非葉子節點命中

圖片.png

可能小夥伴會很奇怪,不是一上來就找到節點五?

一上來找到的實際上是索引,數據它在葉子節點上

圖片.png

咱們能夠看看使用場景來體驗一下B+樹的結構

圖片.png

咱們不想一個一個的檢索,那麼有沒有辦法把這些數據分割成幾部分?

圖片.png

咱們使用什麼算法來體現出這種分割的思想呢?

圖片.png

圖片.png

假如咱們這時使用B+樹的結構尋找28,咱們上來無需從一個節點一個節點開始,只須要找到範圍的索引,一下就過濾了3/2的不符合範圍的數據,某種意義來講比二分還狠

6、B*樹

B*樹的介紹

B* 樹是B+樹的變體,在B+樹的非根和非葉子節點上添加指向兄弟指針的操做

圖片.png

可是B* 樹也有它的規定說明:

第一點:B 樹定義了非葉子節點關鍵字個數至少爲(2/3) M,即塊最低使用率爲2/3,而B+樹的最低使用率爲B+樹的1/2

第二點:從第一點能夠看出,B*樹分配新節點的機率比B+樹要低,空間使用率更高

相關文章
相關標籤/搜索