看圖輕鬆理解數據結構與算法系列(B樹)

前言

推出一個新系列,《看圖輕鬆理解數據結構和算法》,主要使用圖片來描述常見的數據結構和算法,輕鬆閱讀並理解掌握。本系列包括各類堆、各類隊列、各類列表、各類樹、各類圖、各類排序等等幾十篇的樣子。mysql

B樹

B樹即平衡查找樹,通常理解爲平衡多路查找樹,也稱爲B-樹、B_樹。是一種自平衡樹狀數據結構,能對存儲的數據進行O(log n)的時間複雜度進行查找、插入和刪除。B樹通常較多用在存儲系統上,好比數據庫或文件系統。算法

B樹特色

  • B樹能夠定義一個m值做爲預約範圍,即m路(階)B樹。
  • 每一個節點最多有m個孩子。
  • 每一個節點至少有ceil(m/2)個孩子,除了根節點和葉子節點外。
  • 對於根節點,子樹個數範圍爲[2,m],節點內值的個數範圍爲[1,m-1]。
  • 對於非根節點,節點內的值個數範圍爲[ceil(m/2)-1,m-1]。
  • 根節點(非葉子節點)至少有兩個孩子。
  • 一個有k個孩子的非葉子節點包含k-1個值。
  • 全部葉子節點在同一層。
  • 節點內的值按照從小到大排列。
  • 父節點的若干值做爲分離值分紅多個子樹,左子樹小於對應分離值,對應分離值小於右子樹。

如下是一個四階B樹,sql

image

插入

假設如今構建一棵四階B樹,開始插入「A」,直接做爲根節點,數據庫

image

插入「B」,大於「A」,放右邊,網絡

image

插入「C」,按順序排到最後,數據結構

image

繼續插入「D」,直接添加的結果以下圖,此時超過了節點能夠存放容量,對於四階B樹每一個節點最多存放3個值,此時須要執行分裂操做,併發

image

分裂操做爲,先選取待分裂節點的中值,這裏爲「B」,而後將中值「B」放到父節點中,由於這裏尚未父節點,那麼直接建立一個新的父節點存放「B」,而原來小於「B」的那些值做爲左子樹,原來大於「B」的那些值做爲右子樹。機器學習

image

繼續插入「E」,"E"大於「B」,往右子節點,數據結構和算法

image

分別於「C」和「D」比較,大於它們,放到最右邊,學習

image

插入「F」,「F」大於「B」,往右子樹,

image

「F」分別與「C」"D""E"比較,大於它們,放到最右邊,此時觸發分裂操做,

image

選取待分裂節點的中值「D」,而後將中值「D」放到父節點中,父節點中的「B」小於「D」,因而放到「B」右邊,而原來小於「D」的那些值做爲左子樹,原來大於「D」的那些值做爲右子樹。

image

繼續插入「M」,結果爲,

image

插入「L’,大於「B」「D」,往右子樹,

image

「L」大於「E」「F」小於「M」,因而放到第三個位置,此時觸發分裂操做,

image

選取待分裂節點的中值「F」,而後將中值「F」放到父節點中,父節點中的「B」「D」都小於「F」,因而放到最右邊,而原來小於「F」的那些值做爲左子樹,原來大於「F」的那些值做爲右子樹。

image

插入「K」,結果爲,

image

插入「J」,大於「B」「D」「F」,往右子樹,

image

「J」小於「K」「L」「M」,因而放到第一個位置,此時觸發分裂操做,

image

選取待分裂節點的中值「K」,而後將中值「K」放到父節點中,父節點中的「B」「D」「F」都小於「K」,因而放到最右邊,而原來小於「K」的那些值做爲左子樹,原來大於「K」的那些值做爲右子樹。此時父節點也觸發分裂操做,

image

選取待分裂節點的中值「D」,而後將中值「D」放到父節點中,因爲尚未父節點,那麼直接建立一個新的父節點存放「D」,而原來小於「D」的那些值做爲左子樹,原來大於「D」的那些值做爲右子樹。

image

插入「I」,大於「D」,往右子樹,

image

右子樹不是葉子節點,繼續往下,這時「I」大於「F」而小於「K」,因此往第二個分支,

image

「I」小於「J」,因而放到左邊,

image

相似地,插入「H」,結果以下,

image

插入「G」,往左子樹,

image

往中間分支,

image

觸發分裂操做,

image

選取待分裂節點的中值「H」,而後將中值「H」放到父節點中,"H"大於父節點中的「F」而小於「K」,因而放到中間,而原來小於「H」的那些值做爲左子樹,原來大於「H」的那些值做爲右子樹。

image

綜上所述,插入操做的核心是分裂操做。無需分裂的狀況比較簡單,直接插入便可;若是插入後超過節點容量,這個容量可預先自定義,則須要進行分裂操做,須要注意的是分裂可能引發父節點須要繼續分裂。

查找

對B樹進行查找就比較簡單,查找過程有點相似二叉搜索樹,從根節點開始查找,根據比較數值找到對應的分支,繼續往子樹上查找。

好比查找「I」,"I"大於「D」,往右子樹,

image

「I」分別與節點內值比較,大於「F」「H」而小於「K」,往第三個分支,

image

逐一比較節點內的值,找到「I」。

image

-------------推薦閱讀------------

個人開源項目彙總(機器&深度學習、NLP、網絡IO、AIML、mysql協議、chatbot)

爲何寫《Tomcat內核設計剖析》

個人2017文章彙總——機器學習篇

個人2017文章彙總——Java及中間件

個人2017文章彙總——深度學習篇

個人2017文章彙總——JDK源碼篇

個人2017文章彙總——天然語言處理篇

個人2017文章彙總——Java併發篇


跟我交流,向我提問:

歡迎關注:

相關文章
相關標籤/搜索