紅黑樹教程(動畫演示調整過程)--應該是全網最簡單易懂的版本

說明

紅黑樹聽起來挺嚇人,但當你看完這篇文章後再加上紅黑樹在線生成練習幾次,就能夠輕鬆拿下。
下面的教程中x代表當前插入的節點,xpxppxpplxpprunclenephewF(far)nephewC(close)分別爲父節點,祖父節點,祖父節點的左孩子,祖父節點的右孩子,叔叔節點,遠侄子節點,近侄子節點。
左旋:逆時針旋轉
右旋:順時針旋轉
reBalanceAfterInsert():我們在插入後會調用此方法進行再平衡
reBalanceAfterDelete():我們在刪除節點後會調用此方法進行再平衡

紅黑樹的約束

1,根節點必須爲黑色。
2,紅色節點不能有紅色節點的孩子
3,從根節點出發到達葉節點所經過的黑色節點個數相同
4,節點必須爲紅色或黑色
5,一般插入節點爲紅色

數據結構

class RBTreeNode{
        boolean red;
        int val;
        RBTreeNode left;
        RBTreeNode right;
        RBTreeNode parent;
 }

查找

紅黑樹本身就是一種二叉查找樹,所以可以進行二分查找。這與AVL樹或者BST是一致的。

插入

插入時有幾種基本情況,更多複雜的情況都可以轉換成基本情況求解(重點)。左右都是鏡像對稱的。這裏採用右邊插入爲例子。

基本情況1

當前樹爲空,則要插入的節點就是根節點,因此直接插入並將顏色置爲黑。
在這裏插入圖片描述

基本情況2

要插入的節點的父節點爲黑色,此時直接插入節點。因爲增加一個紅色節點不會影響當前插入路徑上黑色節點個數變化。

在這裏插入圖片描述

基本情況3(三點一線)

當要插入的節點存在祖父節點,且不存在叔叔節點時,判斷xxp的位置關係,再判斷xpxpp的位置關係。如果是三個節點中一條線上時,稱爲三點一線。此時我們要做的就是以xp爲圓心,xpp進行左旋。在左旋完成後將xpxpp顏色交換(暴力認爲xp置爲黑色,xpp置爲紅色)

if(xp.right == x){
	// 再判斷xpp
	if(xpp.right == xp){
		// 此時是圖中的情況,這裏稱爲三點一線
	}
}

在這裏插入圖片描述
在這裏插入圖片描述

基本情況4(之字形)

這個情況和基本情況3是類似的。只是結構上不再是三點一線而是一種之字形
處理方式是,將xxp根據位置情況進行旋轉,然後轉換成情況3。當xxp的左孩子時,以x爲圓心xp進行右旋。然後形成三點一線狀態,此時xp位置就是x了,再以x爲圓心,xpp進行左旋,變色即可。
在這裏插入圖片描述

基本情況5

uncle存在且爲紅色時,直接將unclexp變爲黑色,xpp變爲紅色,同時再調用reBalanceAfterInsert()判斷對剩餘樹顏色的影響。從圖中看到,在xpp變爲紅色後會進行reBalanceAfterInsert()將根節點xpp染成黑色。
在這裏插入圖片描述

基本情況6

uncle存在且爲黑色時,只需要以xp爲圓心xpp進行旋轉並將uncle置爲紅色即可。圖中是先進行了情況5的調整,然後再進行情況6的調整。
在這裏插入圖片描述
在這裏插入圖片描述

刪除

對於刪除來說需要考慮的比插入多一點情況,但是也不難。
首先看下整顆紅黑樹形態
在這裏插入圖片描述

基本情況1

刪除的節點爲紅色節點,直接刪除即可,比如刪除550
在這裏插入圖片描述

基本情況2

刪除的節點爲黑色,且無左右子節點。比如刪除50。此時需要判斷nephewF也就是遠侄子節點是否存在,對於上圖50nephewF節點爲160。此時遠侄子節點存在且爲紅色,那麼需要以兄弟節點 150爲圓心,xp 100繞其進行左旋。然後將100160染成黑色。
在這裏插入圖片描述

基本情況3

遠侄子不存在,但是近侄子存在且爲黑色。這裏處理方式和插入時情況4轉成情況3是一樣的。以近侄子爲圓心,兄弟節點繞其旋轉,變成遠侄子的情況,再使用情況2進行處理。
在這裏插入圖片描述

基本情況4

當出現當前節點無孩子,且存在兄弟節點也無孩子,且父節點爲黑色時。
在這裏插入圖片描述
此時假如要刪除150,在刪除後,左子樹路徑黑色節點個數少一個,因此需要將右邊路徑也-1,那麼最快的方法就是將160設置爲紅色,那麼此時對於更大一層的樹而言,155節點那條路上也少了一個黑色節點,則需要再一次調用reBalanceAfterDelete()。可以明顯的看出以155爲調整的節點來說,存在遠侄子節點450,那麼就轉換成情況2。則接下來會以350爲圓心,175繞其進行左旋,然後將250置爲175的右孩子,350變成根節點,然後450被染成黑色。調整結束。

在這裏插入圖片描述
在這裏插入圖片描述

基本情況5

當存在兄弟節點並且父節點爲紅色時。如圖
在這裏插入圖片描述
此時假設刪除200,那麼刪除後左邊路徑黑色節點個數少一個,應該將右邊節點個數也-1,那麼就將300置爲紅色,然後250置爲黑色。調整結束。可以發現在經過上面方法調整後,並沒有對更大層面產生影響。
在這裏插入圖片描述

基本情況6

當節點只有一個孩子且爲紅色時,直接將xp指向child,同時child顏色變成黑色。以刪除155爲例。
![在這裏插入圖片描述](https://img-blog.csdnimg.cn/20200322200355860.png在這裏插入圖片描述
在這裏插入圖片描述

基本情況7

當存在左右孩子時,找到左子樹中最大的節點C,將其值賦給x,然後轉換成對C的刪除操作。
這裏以刪除350爲例,首先找到300,然後將300的值賦給350節點,然後變成對300這個紅色節點的刪除。
在這裏插入圖片描述
可能這個例子太簡單了,這邊還有一個例子供大家學習。
首先找到左子樹最大節點250,然後將250的值賦給300,再變成對250的刪除,此時發現存在近侄子情況,因此是情況3。將以近侄子160爲圓心,155繞其進行一次左旋,隨後變成情況2,再將175160爲圓心進行右旋,調整結束。
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章