看圖輕鬆理解資料結構與演算法系列(B樹的刪除)

超人汪小建發表於2018-09-10

刪除操作

刪除操作比較複雜,主要是因為刪除的項可能在葉子節點上也可能在非葉子節點上,而且刪除後可能導致不符合B樹的規定,這裡暫且稱之為導致B樹不平衡,於是要進行一些合併、左旋、右旋等操作,使之符合B樹的規定(即讓B樹平衡)。另外,如果是刪除非葉子節點項需要先找到中序前驅來替換。

情況一

要刪除的項在葉子節點上且不影響B樹的平衡結構,比如刪除“I”,從根節點開始查詢,“I”大於“D”,往第二個分支,

image

逐一與節點內項的值進行比較,“I”大於“F”,繼續比較,“I”大於“H”繼續比較,“I”小於“K”,所以往第三個分支繼續往下查詢,

image

此時找到“I”,

image

直接刪除“I”,完成刪除操作。

image

情況二

要刪除的項在葉子節點上,刪除後打破平衡需要從右兄弟節點中借項,而且右兄弟節點有足夠的項借給它。比如刪除“G”,從根節點開始查詢,“G”大於“D”,往右子樹,

image

逐一比較節點內項的值,發現應該往第二個分支,

image

找到“G”,

image

此時發現“G”節點的右兄弟節點有項可以借給它,於是刪除“G”,然後進行左旋操作,左旋即原來的父節點“H”下移到左子節點填補原來的“G”節點,右子節點中最小值的項“I”提升到父節點,最終如下,

image

完成刪除操作。

image

情況三

要刪除的項在葉子節點上,刪除後打破平衡需要從左兄弟節點中借項,而且左兄弟節點有足夠的項借給它。比如刪除“L”,從根節點開始查詢,“L”大於“D”,往右子樹,

image

逐一比較節點內項的值,發現應該往第四個分支,

image

找到“L”,

image

此時發現“L”節點的左兄弟節點有項可以借給它,於是刪除“L”,然後進行右旋,右旋即原來的父節點“K”下移到右子節點填補原來的“L”節點,左子節點中最大值的項“J”提升到父節點,最終如下,

image

完成刪除操作。

image

情況四

要刪除的項在葉子節點上,刪除後打破平衡,而且左右兄弟節點都沒有項可以借給它。比如刪除“G”,從根節點開始查詢,“G”大於“D”,往右子樹,

image

逐一比較節點內項的值,發現應該往第二個分支,

image

找到“G”,

image

此時發現“G”節點刪除掉後,左右兄弟節點都無法借項給它,執行合併操作,

image

合併操作主要是將父節點對應的項“F”下移到左子節點中,同時也將右子節點中剩餘的項全部也移到左子節點中(注意這裡右子節點刪除“G”項後已無其他項),最終結果如下,完成刪除操作。

image

需要注意的是如果執行合併操作後使父節點不平衡,則需要繼續對父節點繼續進行平衡處理。比如下面的例子,需要刪除“C”項,從根節點開始於“D”比較,小於“D”則往往第一個分支,

image

逐一與子節點內的項比較,“C”大於“B”則往第二個分支,

image

找到“C”,

image

此時發現“C”項刪除掉後,左右兄弟節點都無法借項給它,

image

執行合併操作,將父節點對應的項“B”下移到左子節點中,同時也將右子節點中剩餘的項全部也移到左子節點中,合併後結果如下,父節點已經變成空了,樹不平衡,

image

此時父節點的右兄弟節點可以借項給它,即執行左旋操作,父節點的父節點“D”下移到父節點,父節點的兄弟節點的最左邊項“F”上升,

image

另外,左旋操作還包括要將移動項“F”對應節點的第一個分支(即“E”)移到父節點“D”的最右分支,最終結果如下,

image

情況五

要刪除的項在非葉子節點上。比如刪除“M”,從根節點開始查詢,“M”大於“H”,往第二個分支,

image

逐一比較子節點內的項,找到“M”,

image

非葉子節點項的刪除的第一步就是要先找到對應的中序前驅,即第一個分支子節點中最大值的項,

image

然後一直往最後一個分支找,最終找到“L”為前驅,將其提升到待刪除項“M”的位置,導致了樹不平衡,但它發現兄弟節點可以借項給它,

image

於是進行右旋操作,父節點“K”下移到原來前驅的位置,左兄弟節點最右邊的項“J”提升到父節點,另外如果左兄弟節點“J”項有右子節點的話,也需要掛到“K”節點的左邊。最終完成刪除操作。

image

除此之外,再看看刪除根節點的情況,刪除只有一個項的根節點,比如刪除“D”,

image

先找中序前驅,即第一個分支子節點中最大值的項,

image

一直往最後一個分支找,最終找到“C”為前驅,將其提升到根節點中,

image

此時引起不平衡,而且原來“C”節點的左右兄弟節點都無法借項給它,

image

此時只能做合併處理,將父節點的項“B”下移到左子節點,合併後原來的父節點變為空,產生了不平衡,此時它的兄弟節點可以借項給它,所以需要執行左旋操作,

image

左旋即將“C”下移,“F”提升,

image

而且還要將“E”項掛到“C”節點上,最終如下。

image

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

我的開源專案彙總(機器&深度學習、NLP、網路IO、AIML、mysql協議、chatbot)

為什麼寫《Tomcat核心設計剖析》

我的2017文章彙總——機器學習篇

我的2017文章彙總——Java及中介軟體

我的2017文章彙總——深度學習篇

我的2017文章彙總——JDK原始碼篇

我的2017文章彙總——自然語言處理篇

我的2017文章彙總——Java併發篇


跟我交流,向我提問:

看圖輕鬆理解資料結構與演算法系列(B樹的刪除)

歡迎關注:

看圖輕鬆理解資料結構與演算法系列(B樹的刪除)

相關文章