說在前面
對於文章中提到的左旋右旋等旋轉詳細過程請參考我的上一篇博客平衡二叉樹插入操作的詳細過程中的解決失衡的口訣方法,其中有旋轉的詳細圖解過程
紅黑樹
-
定義與性質
- 紅黑樹是一種含有紅黑結點並能自平衡的二叉查找樹
- 任意結點都有顏色,紅色或者黑色
- 紅黑樹中根節點一定是黑色的
- 紅黑樹中的 null 位置看作是黑色
- 紅黑樹中紅色不能與紅色相鄰
- 從根到所有 null 的路徑上黑色結點的個數相同
- 紅黑樹中,最長的路徑的長度,不會超過最短的路徑的長度的2倍
- 時間複雜度:Olog(n)
-
插入操作過程
- start:一顆紅黑樹
- 按照搜索樹的特徵進行插入
- 插入時:插入的結點一定是紅色的,如果爲黑色,會破壞第五條規則
- 如果插入的結點是根節點,將顏色改爲黑色
- 插入的結點的父結點是黑色的,則插入完成
- 插入的結點的父結點是紅色的,則需要修復,且繼續向上調整,直到爲根或滿足規則
- 如果根修改之後爲紅色,一定要改過來,改爲黑色
- end:一顆紅黑樹
-
修復方法
- 前提條件:插入的結點(cur)是紅色,cur的父結點(parent)是紅色的,這樣的需要修復
- 修復要點:保證修復操作前和修復操作後的黑色結點的數量不變
- 可推斷出:cur 的祖父結點即父親的父親(grandpa)一定是黑色,否則插入當前結點之前已經違反了紅黑樹的規則
- 如圖:
-
分情況討論:
- 情況1:uncle 存在(uncle != null),並且 uncle 的顏色是紅色
- 修復方法:grandpa 由黑變紅,parent & uncle 由紅變黑;
- eg:
-
情況2:uncle 不存在,或者 uncle 存在但是顏色是黑色
- 情況2.1:cur 是 parent 左孩子,且 parent 是 grandpa 的左孩子**
- 修復方法: grandpa 右旋之後顏色變爲紅色,parent 的顏色變爲黑色
- eg:
- 情況2.2:cur 是 parent 的右孩子,且 parent 是grandpa 的右孩子
- 修復方法:grandpa 左旋後顏色變爲紅色,parent 顏色變爲黑色
- eg:
- 情況2.1:cur 是 parent 左孩子,且 parent 是 grandpa 的左孩子**
- 情況2.3:cur 是 parent 的右孩子 ,parent 是 grandpa 的左孩子
- 修復方法:對 parent 左旋之後將 parent 和 cur 的名稱交換,再按照2.1的情況處理
- eg:
- 情況2.4: cur 是 parent 的左孩子 ,parent 是 grandpa 的右孩子
- 修復方法:對 parent 右旋之後將 parent 和 cur 的名稱交換,再按照2.2的情況處理
- eg:
- 情況1:uncle 存在(uncle != null),並且 uncle 的顏色是紅色
-
演示
- 應用:TreeMap的底層實現