[轉](查找二)2-3查找樹(二叉三叉樹)


為了保證查找樹的平衡性,我們需要一些靈活性,因此在這里我們允許樹中的一個結點保存多個鍵。

2-結點:含有一個鍵(及值)和兩條鏈接,左鏈接指向的2-3樹中的鍵都小於該結點,右鏈接指向的2-3樹中的鍵都大於該結點。

3-結點:含有兩個鍵(及值)和三條鏈接,左鏈接指向的2-3樹中的鍵都小於該結點,中鏈接指向的2-3樹中的鍵都位於該結點的兩個鍵之間,右鏈接指向的2-3樹中的鍵都大於該結點。

(2-3指的是2叉-3叉的意思)


一顆完美平衡的2-3查找樹中的所有空鏈接到根結點的距離都是相同的。

查找

要判斷一個鍵是否在樹中,我們先將它和根結點中的鍵比較。如果它和其中的任何一個相等,查找命中。否則我們就根據比較的結果找到指向相應區間的鏈接,並在其指向的子樹中遞歸地繼續查找。如果這是個空鏈接,查找未命中。

插入

要在2-3樹中插入一個新結點,我們可以和二叉查找樹一樣先進行一次未命中的查找,然后把新結點掛在樹的底部。但這樣的話樹無法保持完美平衡性。我們使用2-3樹的主要原因就在於它能夠在插入之后繼續保持平衡。

如果未命中的查找結束於一個2-結點,我們只要把這個2-結點替換為一個3-結點,將要插入的鍵保存在其中即可。如果未命中的查找結束於一個3-結點,事情就要麻煩一些。

先考慮最簡單的例子:只有一個3-結點的樹,向其插入一個新鍵。

這棵樹唯一的結點中已經沒有可插入的空間了。我們又不能把新鍵插在其空結點上(破壞了完美平衡)。為了將新鍵插入,我們先臨時將新鍵存入該結點中,使之成為一個4-結點。創建一個4-結點很方便,因為很容易將它轉換為一顆由3個2-結點組成的2-3樹(如圖所示),這棵樹既是一顆含有3個結點的二叉查找樹,同時也是一顆完美平衡的2-3樹,其中所有空鏈接到根結點的距離都相等。

向一個父結點為2-結點的3-結點中插入新鍵

假設未命中的查找結束於一個3-結點,而它的父結點是一個2-結點。在這種情況下我們需要在維持樹的完美平衡的前提下為新鍵騰出空間。

我們先像剛才一樣構造一個臨時的4-結點並將其分解,但此時我們不會為中鍵創建一個新結點,而是將其移動至原來的父結點中。(如圖所示)

這次轉換也並不影響(完美平衡的)2-3樹的主要性質。樹仍然是有序的,因為中鍵被移動到父結點中去了,樹仍然是完美平衡的,插入后所有的空鏈接到根結點的距離仍然相同。

向一個父結點為3-結點的3-結點中插入新鍵

假設未命中的查找結束於一個3-結點,而它的父結點是一個3-結點。

我們再次和剛才一樣構造一個臨時的4-結點並分解它,然后將它的中鍵插入它的父結點中。但父結點也是一個3-結點,因此我們再用這個中鍵構造一個新的臨時4-結點,然后在這個結點上進行相同的變換,即分解這個父結點並將它的中鍵插入到它的父結點中去。

我們就這樣一直向上不斷分解臨時的4-結點並將中鍵插入更高的父結點,直至遇到一個2-結點並將它替換為一個不需要繼續分解的3-結點,或者是到達3-結點的根。

總結:

先找插入結點,若結點有空(即2-結點),則直接插入。如結點沒空(即3-結點),則插入使其臨時容納這個元素,然后分裂此結點,把中間元素移到其父結點中。對父結點亦如此處理。(中鍵一直往上移,直到找到空位,在此過程中沒有空位就先搞個臨時的,再分裂。)

2-3樹插入算法的根本在於這些變換都是局部的:除了相關的結點和鏈接之外不必修改或者檢查樹的其他部分。每次變換中,變更的鏈接數量不會超過一個很小的常數。所有局部變換都不會影響整棵樹的有序性和平衡性。

 

參考文章:https://blog.csdn.net/yang_yulei/article/details/26066409


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM