1 2-3樹(shù)
1.1 定義
- 2-結(jié)點(diǎn):含有一個(gè)鍵和兩條孩子(或沒(méi)有),左鏈接指向的2-3樹(shù)中的鍵都小于該結(jié)點(diǎn),右鏈接指向的2-3樹(shù)中的鍵都大于該結(jié)點(diǎn)。
- 3-結(jié)點(diǎn):含有兩個(gè)鍵和三條鏈接(或沒(méi)有),左鏈接指向的2-3樹(shù)中的鍵都小于該結(jié)點(diǎn),中鏈接指向的2-3樹(shù)中的鍵都位于該結(jié)點(diǎn)的兩個(gè)鍵之間,右鏈接指向的2-3樹(shù)中的鍵都大于該結(jié)點(diǎn)。
樹(shù)結(jié)點(diǎn)由2-結(jié)點(diǎn)或者3-結(jié)點(diǎn)組成且所有葉子結(jié)點(diǎn)處于同一高度的樹(shù)(允許是空樹(shù))即為2-3樹(shù)。
1.2 性質(zhì)
- 結(jié)點(diǎn)只能為2-結(jié)點(diǎn)或者3-結(jié)點(diǎn)
- 對(duì)于2-結(jié)點(diǎn)其有一個(gè)數(shù)據(jù),兩個(gè)指針結(jié)點(diǎn)
- 對(duì)于3-結(jié)點(diǎn)其有兩個(gè)數(shù)據(jù),三個(gè)指針結(jié)點(diǎn)
- 所有葉子結(jié)點(diǎn)的高度保持一只高度
1.3 查找
查找過(guò)程與二叉搜索樹(shù)相類(lèi)似。
1.4 插入
遍歷查找結(jié)點(diǎn):
- 查找到則不進(jìn)行插入
- 未查找到,則記錄查找結(jié)束的最后結(jié)點(diǎn)
插入操作可以分為四種類(lèi)型:
- 向2-結(jié)點(diǎn)插入新結(jié)點(diǎn)
- 向僅有一個(gè)3-結(jié)點(diǎn)的樹(shù)中插入新結(jié)點(diǎn)
- 向一個(gè)父結(jié)點(diǎn)為2-結(jié)點(diǎn)的3-結(jié)點(diǎn)中插入新結(jié)點(diǎn)
- 向一個(gè)父結(jié)點(diǎn)為3-結(jié)點(diǎn)的3-結(jié)點(diǎn)插入新結(jié)點(diǎn)
示例:將5,10,15,20,25,30,35,40,45,50依次放入2-3樹(shù)

1.5 刪除
刪除操作也要先進(jìn)行元素的查找,找到才繼續(xù)進(jìn)行刪除操作。
1.5.1 刪除葉子結(jié)點(diǎn)
1.5.1.1 位于三結(jié)點(diǎn)葉子結(jié)點(diǎn)
刪除的元素位于三結(jié)點(diǎn)的葉子結(jié)點(diǎn)上,直接刪除改元素即可,不會(huì)影響整個(gè)樹(shù)的其他結(jié)點(diǎn)。

1.5.1.2 位于二結(jié)點(diǎn)葉子結(jié)點(diǎn)
A. 父結(jié)點(diǎn)是二結(jié)點(diǎn),右孩子是三結(jié)點(diǎn)
直接刪除元素后,會(huì)導(dǎo)致樹(shù)不滿足定義,此時(shí)進(jìn)行左旋。

B.父結(jié)點(diǎn)是二結(jié)點(diǎn),右孩子也是二結(jié)點(diǎn)
通過(guò)中序遍歷,使用前驅(qū)或后繼節(jié)點(diǎn)補(bǔ)位。
如示例先將結(jié)點(diǎn)【20】移到結(jié)點(diǎn)【15】中形成三結(jié)點(diǎn),再將【25】移到原有【20】結(jié)點(diǎn)位置。此時(shí)【30 40】、【35】和【45 50】結(jié)點(diǎn)形成"C.父結(jié)點(diǎn)是三結(jié)點(diǎn)"類(lèi)型的刪除。

C.父結(jié)點(diǎn)是三結(jié)點(diǎn)
刪除節(jié)點(diǎn),意味父節(jié)點(diǎn)不能成為三結(jié)點(diǎn),需要降為二結(jié)點(diǎn)。
如示例將【30】與【35】合并為三結(jié)點(diǎn),作為【40】節(jié)點(diǎn)的左孩子。

D.滿二叉樹(shù)
需要減少層數(shù)。
如示例結(jié)點(diǎn)【10】和【15】合并為三結(jié)點(diǎn)作為結(jié)點(diǎn)【20】左孩子,結(jié)點(diǎn)【30】與【20】合并為三結(jié)點(diǎn)作為根節(jié)點(diǎn)。

1.5.2 刪除非葉子結(jié)點(diǎn)
通過(guò)中序遍歷得到節(jié)點(diǎn)的前驅(qū)或后繼節(jié)點(diǎn),進(jìn)行補(bǔ)位。
2 2-3-4樹(shù)
2-3-4樹(shù)其實(shí)是2-3樹(shù)的擴(kuò)展,包含四結(jié)點(diǎn)的使用。
- 4-結(jié)點(diǎn):含有三個(gè)鍵和四條鏈接(或沒(méi)有),左鏈接指向的2-3-4樹(shù)中的鍵都小于該結(jié)點(diǎn),第二條鏈接指向的2-3-4樹(shù)中的鍵都位于該結(jié)點(diǎn)的第一和第二個(gè)鍵之間,第三條鏈接指向的2-3-4樹(shù)中的鍵都位于該結(jié)點(diǎn)的第二和第三個(gè)鍵之間,右鏈接指向的2-3-4樹(shù)中的鍵都大于該結(jié)點(diǎn)。
由于2-3-4樹(shù)整體與2-3樹(shù)類(lèi)似,故只以示例方式演示其構(gòu)造和刪除。
示例:將5,10,15,20,25,30,35,40,45,50依次放入2-3-4樹(shù)

3 紅黑樹(shù)
2-3-4樹(shù)與紅黑樹(shù)保持平衡的規(guī)則是一致的,并且可以通過(guò)一些規(guī)則進(jìn)行轉(zhuǎn)換。它們是同構(gòu)關(guān)系。
| 2-3-4樹(shù) -> 紅黑樹(shù) | 紅黑樹(shù) -> 2-3-4樹(shù) | |
|---|---|---|
| 轉(zhuǎn)換規(guī)則 | 1. 二結(jié)點(diǎn)轉(zhuǎn)化為紅-黑樹(shù)的黑色結(jié)點(diǎn) 2. 三結(jié)點(diǎn)轉(zhuǎn)化為一個(gè)子結(jié)點(diǎn)和一個(gè)父結(jié)點(diǎn),子結(jié)點(diǎn)涂成紅色,父結(jié)點(diǎn)涂成黑色。 3. 四結(jié)點(diǎn)轉(zhuǎn)化為一個(gè)父結(jié)點(diǎn)和兩個(gè)子結(jié)點(diǎn),子結(jié)點(diǎn)涂成紅色,父結(jié)點(diǎn)涂成黑色。 |
從根結(jié)點(diǎn)開(kāi)始遍歷: 1.黑色結(jié)點(diǎn)為二結(jié)點(diǎn) 2.紅色結(jié)點(diǎn)與其父結(jié)點(diǎn)合并升級(jí)為多節(jié)點(diǎn) |

紅黑樹(shù)的結(jié)構(gòu)與2-3-4樹(shù)對(duì)應(yīng),而且兩種樹(shù)操作也一樣。
2-3-4樹(shù)用結(jié)點(diǎn)分裂保持平衡,紅-黑樹(shù)用顏色變換和旋轉(zhuǎn)保持平衡。
3.1 定義
1.每個(gè)結(jié)點(diǎn)要么是紅的,要么是黑的。
2.根結(jié)點(diǎn)是黑的。
3.每個(gè)葉結(jié)點(diǎn),即空結(jié)點(diǎn)(NIL)是黑的。
4.如果一個(gè)結(jié)點(diǎn)是紅的,那么它的倆個(gè)兒子都是黑的。
5.對(duì)每個(gè)結(jié)點(diǎn),從該結(jié)點(diǎn)到其子孫結(jié)點(diǎn)的所有路徑上包含相同數(shù)目的黑結(jié)點(diǎn)。
3.2 插入
基本流程:
- 將紅黑樹(shù)當(dāng)作一顆二叉查找樹(shù),將結(jié)點(diǎn)插入
- 將插入的結(jié)點(diǎn)著色為紅色
- 通過(guò)一系列的旋轉(zhuǎn)或著色等操作,使之重新成為一顆紅黑樹(shù)
其中旋轉(zhuǎn)著色根據(jù)插入的結(jié)點(diǎn)父結(jié)點(diǎn)情況分為以下三種類(lèi)型:
3.2.1 插入根結(jié)點(diǎn)
直接改為黑色
3.2.2 插入結(jié)點(diǎn)的父結(jié)點(diǎn)是黑色

3.2.3 插入結(jié)點(diǎn)的父結(jié)點(diǎn)是紅色
處理思路:將紅色的結(jié)點(diǎn)移到根結(jié)點(diǎn),再將根結(jié)點(diǎn)設(shè)為黑色。
實(shí)際又可以細(xì)化如下幾種情況:
3.2.3.1 叔叔結(jié)點(diǎn)為紅色
處理步驟:
- 父結(jié)點(diǎn)設(shè)置為黑色
- 叔叔結(jié)點(diǎn)設(shè)置為黑色
- 祖父結(jié)點(diǎn)設(shè)為紅色
- 祖父結(jié)點(diǎn)設(shè)為“當(dāng)前結(jié)點(diǎn)”,繼續(xù)向上遍歷
3.2.3.2 父結(jié)點(diǎn)是左結(jié)點(diǎn),叔叔結(jié)點(diǎn)是黑色
處理步驟:
- 對(duì)祖父節(jié)點(diǎn)右旋
- 父結(jié)點(diǎn)設(shè)為黑色
- 祖父節(jié)點(diǎn)設(shè)為紅色
3.2.3.3 父結(jié)點(diǎn)是右結(jié)點(diǎn),叔叔結(jié)點(diǎn)是黑色
處理步驟:
- 對(duì)父結(jié)點(diǎn)左旋
- 按照步驟二處理
詳細(xì)圖解:

3.3 刪除
3.3.1 葉子結(jié)點(diǎn)
3.3.1.1 葉子結(jié)點(diǎn)是紅色
無(wú)需處理
3.3.1.2 葉子結(jié)點(diǎn)是黑色
當(dāng)前結(jié)點(diǎn)是左結(jié)點(diǎn):




E. 兄弟結(jié)點(diǎn)設(shè)為紅色,父結(jié)點(diǎn)設(shè)為遞歸結(jié)點(diǎn)遞歸,指導(dǎo)根節(jié)點(diǎn)或紅色節(jié)點(diǎn)

當(dāng)前結(jié)點(diǎn)是右結(jié)點(diǎn):




E. 兄弟結(jié)點(diǎn)設(shè)為紅色,父結(jié)點(diǎn)設(shè)為遞歸結(jié)點(diǎn)遞歸,指導(dǎo)根節(jié)點(diǎn)或紅色節(jié)點(diǎn)

3.3.2 非葉子結(jié)點(diǎn),只有一個(gè)結(jié)點(diǎn)
父結(jié)點(diǎn)P下面只有一個(gè)子節(jié)點(diǎn)C,則可以將結(jié)點(diǎn)P和節(jié)點(diǎn)C交換,則可以轉(zhuǎn)換成【3.3.1 葉子結(jié)點(diǎn)】情景。
3.3.3 非葉子結(jié)點(diǎn),有兩個(gè)子結(jié)點(diǎn)
刪除的結(jié)點(diǎn)有兩個(gè)子節(jié)點(diǎn),通過(guò)交換結(jié)點(diǎn)P和后繼節(jié)點(diǎn)N的方式,將刪除結(jié)點(diǎn)P轉(zhuǎn)化為結(jié)點(diǎn)N。
后繼結(jié)點(diǎn)N分為兩種情況:
- 是葉子結(jié)點(diǎn)【3.3.1 葉子結(jié)點(diǎn)】
- 有一個(gè)子結(jié)點(diǎn)【3.3.2 非葉子結(jié)點(diǎn),只有一個(gè)結(jié)點(diǎn)】