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

前言

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

2-3樹

2-3樹,是最簡單的B-樹,其中二、3主要體如今每一個非葉子節點都有2個或3個子節點,B-樹便是平衡樹,平衡樹是爲了解決不平衡樹查詢效率問題,常見的二叉平衡書有AVL樹,它雖然提升了查詢效率,可是插入操做效率不高,由於它須要再每次插入節點後維護樹的平衡,而爲了解決查詢效率同時有兼顧插入效率,因而提出了2-3樹。算法

2-3樹特色

  • 2-3樹是一棵平衡樹,但不是二叉平衡樹。
  • 對於高度相同的2-3樹和二叉樹,2-3樹的節點數要大於滿二叉樹,由於有些節點可能有三個子節點。
  • 2-3樹能夠是一棵空樹。
  • 對於2節點來講,該節點保存了一個key及對應的value,除此以外還保存了指向左右兩邊的子節點,子節點也是一個2-3節點,左子節點全部值小於key,右子節點全部值大於key。
  • 對於3節點來講,該節點保存了兩個key及對應的value,除此以外還保存了指向左中右三個方向的子節點,子節點也是一個2-3節點,左子節點的全部值小於兩個key中較小的那個,中節點的全部值在兩個key值之間,右子節點大於兩個key中較大的那個。
  • 對2-3樹進行中序遍歷能獲得一個排好序的序列。

image

插入操做

剛開始是空樹,插入節點「A」,建立根節點,sql

image

插入節點「B」,從根節點開始尋找存放的節點位置,與「A」節點合併後放到同一個葉子上,此時該葉子只包含「AB」兩個項目,無需分裂,網絡

image

繼續插入節點「C」,從根節點開始尋找存放的節點位置,找到「AB」葉子節點,將其放進去,數據結構

image

但此時該葉子節點包含了「ABC」三個項目,須要將該節點進行分裂操做,分裂的具體過程以下,找到該節點三個項目中中間大的項,併發

image

上移成爲最小項和最大項的父節點,而最小項做爲中間項的左子節點,最大項做爲中間項的右子節點。機器學習

image

繼續插入「D」節點,從根節點開始尋找,數據結構和算法

image

大於「B」,因此往右,學習

image

找到「C」節點,併合併到該葉子節點,該節點只有兩個項目,沒必要分裂。.net

image

繼續插入「E」,查找到「CD」葉子節點,放入「E」節點後發現該葉子節點有三個項目,須要分裂,

image

將中間項提高到父節點,其他兩項分裂成兩個子節點,「D」上升到父節點後存放在右邊,並且父節點只有兩個項目,沒必要再繼續分裂。

image

繼續插入「F」節點,

image

往下看連續分裂兩次的狀況,繼續插入「G」節點,大於「B」,繼續比較,

image

大於「D」,往右子節點,

image

到右子節點後與「F」比較,發現大於「F」,放到右邊,

image

image

發現「EFG」葉子節點有三個項目,必須分裂,

image

將中間項「F」提高到父節點,「E」和「G」左右兩項分別稱爲左右子節點,

image

提高到父節點後發現父節點包含了「BDF」三項,也須要分裂,因而準備將中間項「F」提高,

image

發現「BDF」節點原本屬於根節點,那麼分裂後就沒有根節點了,因而須要建立一個新節點做爲根節點,即提高的「D」節點做爲新的根節點。「B」和「F」左右兩項分別做爲左右子節點。

image

總結起來就是:一個節點插入到一棵2-3樹中,先尋找該節點應該落到哪一個葉子節點上,注意必定是在葉子節點。將新節點做爲一個新項加入到葉子節點中,此時若是該節點只有兩個項目,則完成插入操做。但若是該節點有三個項目,則須要進行分裂操做,左中右三項按大小排序,將中間項提高到父節點中,而左右兩項做爲左右子節點,而後可能還沒完,由於父節點上可能又包含了三個項目,若是是這樣還得作分裂操做,一直遞歸到父節點只包含一個或兩個項目。

查找

2-3樹的查找與二叉樹的查找相似,從根節點開始比較,若是相等則查找成功,不然往下繼續查找,對於只有兩個子節點的節點則在其左右子樹中遞歸查找,而對於有三個子節點的節點則須要在左中右子樹中遞歸查找。

以下2-3樹,查找「C」節點,

image

從根節點開始,與「D」比較,「C」小於「D」則往左,

image

繼續與「B」比較,「C」大於「B」則往右,

image

「C」與「C」相等,找到。

image

若是要查找「H」節點,從根節點開始,「H」大於「D」則往右,

image

在「FH」節點中逐個項比較,先跟「F」項比較,「H」大於「F」,繼續比較下一項,

image

「H」等於「H」,找到,在「FH」節點中找到「H」。

image

若是要查找「G」節點,從根節點開始,「G」大於「D」則往右,

image

「G」與「FH」節點逐個比較,大於「F」,繼續比較下一項,

image

「G」小於「H」,即「G」間於「F」和「H」之間,因而往中間,

image

「G」等於「G」,找到。

image

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

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

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

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

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

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

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

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

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


跟我交流,向我提問:

歡迎關注:

相關文章
相關標籤/搜索