手撕紅黑樹

2021-10-08 01:19:39 字數 3771 閱讀 9208

提示

這篇部落格主要是我對紅黑樹一些認識,如果你想較全面的了解紅黑樹推薦下面這兩個,演算法4和演算法導論也有較全面的講解。

美團技術團隊

30張圖帶你徹底理解紅黑樹

初識紅黑樹

每個節點或者是紅色的,或者是黑色的。

根節點是一定是黑色的,2-3樹中,當根節點是二節點的時候明顯對應為黑色,當跟節點是三節點的時候,紅黑樹中對應的紅節點就跑到坐下角了。

每乙個葉子節點(指最後的空節點,並不指左右節點都為空的那個節點)是黑色的相當於定義了空節點本身就是乙個黑色的節點

每個紅色結點的兩個子結點一定都是黑色。(父子節點之間不能出現兩個連續的紅節點)

任意一結點到每個葉子結點的路徑都包含數量相同的黑結點。

開始手撕紅黑樹(**是跟著劉宇波老師的課程實現的)

結點定義

class

node

comparable

>

public

node

(t value)

public

node

(t value,

boolean isred)

public t getvalue()

void

setvalue

(t value)

node

getleft()

void

setleft

(node

left)

node

getright()

void

setright

(node

right)

node

getparent()

void

setparent

(node

parent)

boolean

isred()

boolean

isblack()

/** * is leaf node

**/boolean

isleaf()

void

setred

(boolean red)

void

makered()

void

makeblack()

@override

public string tostring()

}

左旋轉

/**左旋轉

* node x

* / \ 左旋轉 / \

* t1 x ---------> node t3

* / \ / \

* t2 t3 t1 t2

* */

private node leftrotate

(node node)

右旋轉

/**右旋轉

* node x

* / \ 右旋轉 / \

* x t2 -------> y node

* / \ / \

* y t1 t1 t2

* */

private node rightrotate

(node node)

顏色翻轉

// 顏色翻轉,向3節點新增乙個節點(節點對應的位置在右子樹,

// 子節點變黑,父節點變紅和上層進行融合)

private

void

flipcolors

(node node)

新增節點

由於我們使用的是簡化版的左傾紅黑樹,對於某些場景還需要特殊處理

場景3,當插入節點為父節點的左節點時,直接插入;當插入節點為父節點的右節點時,需要進行左旋轉。

場景4.1 不存在。

// 向紅黑樹中新增新的元素(key, value)

public

void

add(k key, v value)

// 向以node為根的紅黑樹中插入元素(key, value),遞迴演算法

// 返回插入新節點後紅黑樹的根

private node add

(node node, k key, v value)

if(key.

compareto

(node.key)

<0)

node.left =

add(node.left, key, value)

;else

if(key.

compareto

(node.key)

>0)

node.right =

add(node.right, key, value)

;else

// key.compareto(node.key) == 0

node.value = value;

// 維護紅黑樹!!!!

// 左旋轉(對應兩種情況!)if(

isred

(node.right)&&!

isred

(node.left)

) node =

this

.leftrotate

(node.left)

;// 右旋轉if(

isred

(node.left)

&&isred

(node.left.left)

) node =

this

.rightrotate

(node.left)

;// 顏色翻轉if(

isred

(node.left)

&&isred

(node.right)

)this

.flipcolors

(node)

;return node;

}

左傾紅黑樹相對來說比較容易理解,但是為了維護「左傾」這個性質,做了額外的事情,消耗了效能,沒有「任何不平衡都可以在三次旋轉內解決」這麼好的效能優勢。

刪除節點

刪除節點的過程,參考美團技術團隊(這個實現的是優化的紅黑樹)

紅黑樹其他的功能實現跟其他平衡二叉樹差不多。

參考劉宇波老師的玩轉資料結構

30張圖帶你徹底理解紅黑樹

美團技術團隊

紅黑樹下 紅黑樹的實現

1.實現紅黑樹的基本思想 實際上,紅黑樹是有固定的平衡過程的 遇到什麼樣的節點分布,我們就對應怎麼去調整。只要按照這些固定的調整規則來操作,就能將乙個非平衡的紅黑樹調整成平衡的。首先,我們需要再來看一下紅黑樹的定義 在插入 刪除節點的過程中,第 三 四點要求可能會被破壞,所以 平衡調整 實際上就是把...

紅黑樹下 紅黑樹的實現

1.實現紅黑樹的基本思想 實際上,紅黑樹是有固定的平衡過程的 遇到什麼樣的節點分布,我們就對應怎麼去調整。只要按照這些固定的調整規則來操作,就能將乙個非平衡的紅黑樹調整成平衡的。首先,我們需要再來看一下紅黑樹的定義 在插入 刪除節點的過程中,第 三 四點要求可能會被破壞,所以 平衡調整 實際上就是把...

紅黑樹筆記 紅黑樹的插入操作

紅黑樹的插入操作可以在o logn 的時間內完成。開始插入節點的時候和二叉查詢樹一樣,只需要最後將插入的節點著成紅色,為了保證紅黑樹的性質,需要通過rb insertfixup函式來調整該節點,對其重新著色並旋轉。下面先呼叫rb insert 函式將乙個節點插入到紅黑樹中,同樣先上偽 rb inse...