B樹詳解

由于數(shù)據(jù)結(jié)構(gòu)的東西涉及到許多的圖片啊蝉绷,流程啊什么的田度。所以會參考許多網(wǎng)上存在的資料加以總結(jié)默怨,我會將參考鏈接放在文章后面幕庐。

B樹

B樹基本概念

網(wǎng)上的許多資料在講述數(shù)據(jù)結(jié)構(gòu)之前都會講相關(guān)的一些符合久锥、說明以及特性什么的都交代清除。在閱讀網(wǎng)上資料的時候我發(fā)現(xiàn)許多知識點說的都非常的官方异剥,簡單來說就是賊難看懂瑟由。所以我在記錄的時候會將那些難懂的官方內(nèi)容用通俗的話解釋一下,方便我自己的理解届吁。

首先來說错妖,為什么我們要引入B樹呢?有二叉樹不是很好嗎疚沐?

存在即合理暂氯。所以還是有存在的理由的。B樹的時間復(fù)雜度與二叉樹一樣亮蛔,均為O(logN)痴施。然而B樹出現(xiàn)是因為磁盤IO。IO操作的效率很低究流,那么辣吃,當(dāng)在大量數(shù)據(jù)存儲中,查詢時我們不能一下子將所有數(shù)據(jù)加載到內(nèi)存中芬探,只能逐一加載磁盤頁神得,每個磁盤頁對應(yīng)樹的節(jié)點。造成大量磁盤IO操作(最壞情況下為樹的高度)偷仿。平衡二叉樹由于樹深度過大而造成磁盤IO讀寫過于頻繁哩簿,進而導(dǎo)致效率低下宵蕉。
  所以,我們?yōu)榱藴p少磁盤IO的次數(shù)节榜,就你必須降低樹的深度羡玛,將“瘦高”的樹變得“矮胖”。

PS:這里我找到了一個講述很好的二叉樹與B樹的比較鏈接宗苍。大家可以閱讀以下稼稿。

http://m.elecfans.com/article/662237.html

比如下面的圖片:

二叉樹
B樹

二叉樹以2為最大基準(zhǔn)向下延伸,而B樹則沒有標(biāo)準(zhǔn)讳窟,所以它可以變得矮矮胖胖的让歼。

B 樹又叫平衡多路查找樹。一棵m階的B 樹 (m叉樹)的特性如下

  • B樹中所有節(jié)點的孩子節(jié)點數(shù)中的最大值稱為B樹的階挪钓,記為M(重點

  • 樹中的每個節(jié)點至多有M棵子樹 ---即:如果定了M是越,則這個B樹中任何節(jié)點的子節(jié)點數(shù)量都不能超過M

  • 若根節(jié)點不是終端節(jié)點,則至少有兩棵子樹

  • 除根節(jié)點和葉節(jié)點外碌上,所有點至少有m/2棵子樹(上溢)

  • 所有的葉子結(jié)點都位于同一層。(比如上面的圖片中我沒有了11 13 15浦徊,那么我12就沒有存在的意義了馏予,就需要調(diào)整整個樹的布局)

下面是我在百科中找到的性質(zhì):

image.png

B樹的查找操作

查找操作的理解不難。我直接用幾張圖來闡述一下盔性。

在B樹上進行查找和二叉樹的查找很相似霞丧,二叉樹是每個節(jié)點上有一個關(guān)鍵子和兩個分支。B樹上每個節(jié)點有K個關(guān)鍵字和K+1個分支冕香。二叉樹的查找只考慮向左還是向右走蛹尝,而B樹中需要由多個分支決定。

B樹的查找分兩步悉尾,首先查找節(jié)點突那,由于B樹通常是在磁盤上存儲的所以這步需要進行磁盤IO操作。第二步是查找關(guān)鍵字构眯,當(dāng)找到某個節(jié)點后將該節(jié)點讀入內(nèi)存中然后通過順序或者折半查找來查找關(guān)鍵字愕难。若沒有找到關(guān)鍵字,則需要判斷大小來找到合適的分支繼續(xù)查找惫霸。

如下有一個3階的B樹猫缭,觀察查找元素21的過程:

image.png

第一次磁盤IO:

image.png

第二次磁盤IO:

image.png

這里有一次內(nèi)存比對:分別跟3與12比對。

第三次磁盤IO:

這里有一次內(nèi)存比對壹店,分別跟14與21比對

PS:此處參考:http://m.elecfans.com/article/662237.html

由于B樹相對于二叉樹來說矮胖了許多猜丹,所以它所涉及的IO操作也相對少了許多。不過根據(jù)我們上面的分析硅卢,其在查找數(shù)據(jù)的時候并沒有減少比較次數(shù)射窒。但是我們知道藏杖,我們在比較數(shù)據(jù)的時候是在內(nèi)存中進行的,所以相對來說時間上會更加迅速轮洋,幾乎可以忽略制市。

而相同數(shù)量的key在B樹中生成的節(jié)點要遠遠少于二叉樹中的節(jié)點,相差的節(jié)點數(shù)量就等同于磁盤IO的次數(shù)弊予。這樣到達一定數(shù)量后祥楣,性能的差異就顯現(xiàn)出來了。

這里先放下一個問題汉柒,既然我的介數(shù)M是自行設(shè)定的误褪。那么我們的M如果很小那么會變成類似于二叉樹,那么當(dāng)M很大的時候呢碾褂?

我認為當(dāng)M很大會導(dǎo)致比較次數(shù)過多兽间,在當(dāng)前磁盤空間能容納的范圍下也有可能導(dǎo)致比較次數(shù)過多而導(dǎo)致效率降低的情況。

B樹的插入

對高度為k的m階B樹正塌,新結(jié)點一般是插在葉子層嘀略。通過檢索可以確定關(guān)鍵碼應(yīng)插入的結(jié)點位置。然后分兩種情況討論:
  1乓诽、 若該結(jié)點中關(guān)鍵碼個數(shù)小于m-1帜羊,則直接插入即可。
  2鸠天、 若該結(jié)點中關(guān)鍵碼個數(shù)等于m-1讼育,則將引起結(jié)點的分裂。以中間關(guān)鍵碼為界將結(jié)點一分為二稠集,產(chǎn)生一個新結(jié)點奶段,并把中間關(guān)鍵碼插入到父結(jié)點(k-1層)中
  重復(fù)上述工作,最壞情況一直分裂到根結(jié)點剥纷,建立一個新的根結(jié)點痹籍,整個B樹增加一層。

例如:在下面的B樹中插入key:4

image.png

第一步:檢索key插入的節(jié)點位置如上圖所示筷畦,在3,5之間词裤;

第二步:判斷節(jié)點中的關(guān)鍵碼個數(shù):
  節(jié)點3,5已經(jīng)是兩元素節(jié)點鳖宾,無法再增加(已經(jīng) = 3-1)吼砂。父親節(jié)點 2, 6 也是兩元素節(jié)點鼎文,也無法再增加渔肩。根節(jié)點9是單元素節(jié)點,可以升級為兩元素節(jié)點拇惋。周偎;

第三步:結(jié)點分裂:
  拆分節(jié)點3抹剩,5與節(jié)點2,6蓉坎,讓根節(jié)點9升級為兩元素節(jié)點4澳眷,9。節(jié)點6獨立為根節(jié)點的第二個孩子蛉艾。

最終結(jié)果如下圖:雖然插入比較麻煩钳踊,但是這也能確保B樹是一個自平衡的樹。

image.png

另一個例子:

image.png

當(dāng)插入一個關(guān)鍵字60后,節(jié)點內(nèi)的關(guān)鍵字個數(shù)超過出了m-1=2勿侯,此時必須進行節(jié)點分裂拓瞪,分裂的過程如上圖所示。

資源來源參考于:https://blog.csdn.net/z_ryan/article/details/79685072

B樹的刪除

B樹的刪除操作相對較為復(fù)雜助琐,我看許多文檔解釋的都十分官方且難懂祭埂。所以我準(zhǔn)備用更為簡單的圖來對刪除操作的不同情況進行解釋。希望大家看完后能夠理解兵钮。

  • 首先蛆橡,根據(jù)key刪除記錄,如果B樹中的記錄中不存對應(yīng)key的記錄掘譬,則刪除失敗航罗。

之后我們需要分一下四種情況來考慮。(下面的例子中以5階B樹為例屁药,介紹B樹的刪除操作,5階B樹中柏锄,結(jié)點最多有4個key,最少有2個key)對于刪除key的過程來說酿箭,對于葉結(jié)點和非葉結(jié)點其實差別在一個地方,那就是如果當(dāng)前我們操作的是非葉結(jié)點趾娃,那么后繼key(這里的后繼key指最接近當(dāng)前刪除值缭嫡,且大于當(dāng)前刪除值的值)覆蓋要刪除的key,然后在后繼key所在的子支中刪除該后繼key抬闷。

例如:

a)原始狀態(tài)

image.png

b)在上述情況下接著刪除27妇蛀。從上圖可知27位于非葉子結(jié)點中,所以用27的后繼替換它笤成。從圖中可以看出评架,27的后繼為28,我們用28替換27炕泳,然后在28(原27)的右孩子結(jié)點中刪除28纵诞。刪除后的結(jié)果如下圖所示。

image.png

之后我們就把非葉結(jié)點的情況轉(zhuǎn)換為了處理葉結(jié)點的情況培遵。

此時我們就要分一下幾種情況來考慮如何處理葉結(jié)點浙芙。

  • ①該結(jié)點key個數(shù)>=Ceil(m/2)-1(上界登刺,例如m=5,那么最后為2)嗡呼,結(jié)束刪除操作纸俭,否則執(zhí)行下一步。
  • ②該結(jié)點key的個數(shù)<Ceil(m/2)-1南窗,且兄弟結(jié)點key個數(shù)>Ceil(m/2)-1揍很,則父結(jié)點中的key下移到該結(jié)點,兄弟結(jié)點中的一個key上移矾瘾,刪除操作結(jié)束女轿。

a)緊接上面的例子。

image.png

b)刪除后發(fā)現(xiàn)壕翩,當(dāng)前葉子結(jié)點的記錄的個數(shù)小于2(<Ceil(m/2)-1)蛉迹,而它的兄弟結(jié)點中有3個記錄(>Ceil(m/2)-1 當(dāng)前結(jié)點還有一個右兄弟,選擇右兄弟就會出現(xiàn)合并結(jié)點的情況放妈,不論選哪一個都行北救,只是最后B樹的形態(tài)會不一樣而已),我們可以從兄弟結(jié)點中借取一個key芜抒。所以父結(jié)點中的28下移珍策,兄弟結(jié)點中的26上移,刪除結(jié)束宅倒。結(jié)果如下圖所示攘宙。

image.png
  • ③如果該結(jié)點key的個數(shù)<Ceil(m/2)-1,且兄弟結(jié)點key個數(shù)<=Ceil(m/2)-1拐迁,那么將父結(jié)點中的key下移與當(dāng)前結(jié)點及它的兄弟結(jié)點中的key合并蹭劈,形成一個新的結(jié)點。原父結(jié)點中的key的兩個孩子指針就變成了一個孩子指針线召,指向這個新結(jié)點铺韧。

例如:

a)原圖為

image.png

b)在上述情況下刪除32。

image.png

當(dāng)刪除后缓淹,當(dāng)前結(jié)點中只有一個key(個數(shù)<Ceil(m/2)-1)哈打,而兄弟結(jié)點中也僅有2個key(<=Ceil(m/2)-1)。所以只能讓父結(jié)點中的30下移和這個兩個孩子結(jié)點中的key合并讯壶,成為一個新的結(jié)點料仗,當(dāng)前結(jié)點的指針指向父結(jié)點。結(jié)果如下圖所示鹏溯。

image.png

由于我們移動了父結(jié)點中的數(shù)據(jù)罢维,所以其key值減少,那么我們就要對當(dāng)前父結(jié)點進行考慮。

下面看一個考慮父結(jié)點的例子肺孵。

a)原圖

image.png

b)上述情況下匀借,我們接著刪除key為40的記錄,刪除后結(jié)果如下圖所示平窘。

image.png

同理吓肋,當(dāng)前結(jié)點的記錄數(shù)小于2(根據(jù)情況③),兄弟結(jié)點中沒有多余key瑰艘,所以父結(jié)點中的key下移是鬼,和兄弟(這里我們選擇左兄弟,選擇右兄弟也可以)結(jié)點合并紫新,合并后的指向當(dāng)前結(jié)點的指針就指向了父結(jié)點均蜜。

image.png

同理,對于當(dāng)前結(jié)點而言只能繼續(xù)合并了芒率,最后結(jié)果如下所示囤耳。(根據(jù)情況③

image.png

合并后結(jié)點當(dāng)前結(jié)點滿足條件,刪除結(jié)束偶芍。

此處參考了部分:https://www.cnblogs.com/nullzx/p/8729425.html的內(nèi)容充择。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市匪蟀,隨后出現(xiàn)的幾起案子椎麦,更是在濱河造成了極大的恐慌,老刑警劉巖材彪,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件观挎,死亡現(xiàn)場離奇詭異,居然都是意外死亡段化,警方通過查閱死者的電腦和手機键兜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來穗泵,“玉大人,你說我怎么就攤上這事谜疤〉柩樱” “怎么了?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵夷磕,是天一觀的道長履肃。 經(jīng)常有香客問我,道長坐桩,這世上最難降的妖魔是什么尺棋? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮绵跷,結(jié)果婚禮上膘螟,老公的妹妹穿的比我還像新娘成福。我一直安慰自己,他們只是感情好荆残,可當(dāng)我...
    茶點故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布奴艾。 她就那樣靜靜地躺著,像睡著了一般内斯。 火紅的嫁衣襯著肌膚如雪蕴潦。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天俘闯,我揣著相機與錄音潭苞,去河邊找鬼。 笑死真朗,一個胖子當(dāng)著我的面吹牛此疹,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蜜猾,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼秀菱,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了蹭睡?” 一聲冷哼從身側(cè)響起衍菱,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎肩豁,沒想到半個月后脊串,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡清钥,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年琼锋,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片祟昭。...
    茶點故事閱讀 39,919評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡缕坎,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出篡悟,到底是詐尸還是另有隱情谜叹,我是刑警寧澤,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布搬葬,位于F島的核電站荷腊,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏急凰。R本人自食惡果不足惜女仰,卻給世界環(huán)境...
    茶點故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧疾忍,春花似錦乔外、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至擒抛,卻和暖如春推汽,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背歧沪。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工歹撒, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人诊胞。 一個月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓暖夭,卻偏偏與公主長得像,于是被迫代替她去往敵國和親撵孤。 傳聞我的和親對象是個殘疾皇子迈着,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,864評論 2 354

推薦閱讀更多精彩內(nèi)容

  • B樹的定義 一棵m階的B樹滿足下列條件: 樹中每個結(jié)點至多有m個孩子。 除根結(jié)點和葉子結(jié)點外邪码,其它每個結(jié)點至少有m...
    文檔隨手記閱讀 13,221評論 0 25
  • 具體講解之前裕菠,有一點,再次強調(diào)下:B-樹闭专,即為B樹奴潘。因為B樹的原英文名稱為B-tree,而國內(nèi)很多人喜歡把B-tr...
    文哥的學(xué)習(xí)日記閱讀 93,775評論 11 86
  • B樹 1.前言: 動態(tài)查找樹主要有:二叉查找樹(Binary Search Tree)影钉,平衡二叉查找樹(Balan...
    鐵甲依然在_978f閱讀 1,447評論 0 4
  • 原文鏈接 B樹 1.前言: 動態(tài)查找樹主要有:二叉查找樹(Binary Search Tree)画髓,平衡二叉查找樹(...
    非典型程序員閱讀 1,159評論 0 3
  • 晚上兵哥過生日,喊我一塊平委,加上我女朋友奈虾,共三人。點了四個菜廉赔,兩瓶白酒愚墓,我實在不會挑禮物,帶了一個小蛋糕昂勉。菜剩一大半...
    定云止水_0cc5閱讀 171評論 0 0