日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

红黑树,看不懂你找我

發布時間:2025/6/17 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 红黑树,看不懂你找我 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 一:什么是紅黑樹
  • 二:關于紅黑樹的一般操作
    • 1.查找操作
    • 2. 插入操作
      • 2.1 新節點:我是紅色的,我爹是紅色的,我叔叔是黑色的
      • 2.2 新節點:我是紅色的,我爹是紅色的,我叔叔也是紅色的
    • 3.刪除操作
      • 3.1替代點是紅色的
      • 3.2替代點是黑色的
        • 3.2.1 有一個兒子為且必須為紅色時
        • 3.2.2 有兩個黑色兒子
          • 3.2.2.1 替代點的兄弟節點是紅色
          • 3.2.2.2 替代點的兄弟節點是黑色
            • 3.2.2.2.1 當兄弟節點的兩個兒子也都是黑色
            • 3.2.2.2.2 當兄弟節點的左兒子是紅色的,右兒子是黑色
            • 3.2.2.2.3 當兄弟節點的右兒子是紅色的,左兒子隨意
  • 三:漸進邊界的證明

一:什么是紅黑樹

紅黑樹是AVL樹的一種流行變種,是具有以下五個特點的二叉查找樹

  • 每一個節點或者著成紅色,或者著成黑色
  • 根是黑色
  • 每個葉節點Nil是黑色
  • 如果一個節點是紅色的,那么它的子節點必須是黑色的
  • 每一條從某節點到某Nil指針的路徑必須包含相同數目的黑色節點
  • 二:關于紅黑樹的一般操作

    對紅黑樹操作,最困難的就是保持上述的紅黑樹性質中的紅色標記部分。

    1.查找操作

    紅黑樹是二叉查找樹,所以其查找操作與一般的二叉查找樹相同

    • 令根節點為當前節點
    • 當前節點為Nil,返回Nil
    • 要找的值等于當前節點,返回當前節點
    • 要找的值大于當前節點, 令右兒子為當前節點,重復步驟2
    • 要找的值小于當前節點,令左兒子為當前節點,重復步驟2

    操作的時間復雜度O(logN)

    2. 插入操作

    當我們想向樹中插入一個新節點時,通常把這個節點作為葉節點插入。

    Part1:
    假設把這個點涂成黑色,那完了,肯定違反了條件5,因為本來任意的節點到某Nil指針的路徑中黑色節點數是相同的,現在加上黑色節點的這條路徑黑色節點數度肯定會+1,于是原來的條件被破壞了,因此,新加的節點必須被涂成紅色

    Part2:
    如果新插入的節點的父節點是黑色的,那么直接插入新的紅節點就完事了

    Part3:
    如果新插入的節點的父節點是紅色,那么條件4就被破壞了,這種情況下,我們必須在保持條件5不被破壞的同時,利用改變節點顏色以及樹的旋轉來滿足所有條件。

    2.1 新節點:我是紅色的,我爹是紅色的,我叔叔是黑色的

    • 設置P為黑色
    • 設置G為紅色
    • 進行右單旋轉

    • 設置X為黑色
    • 設置G為紅色
    • 進行右雙旋轉

    還有對稱的兩種情況,操作也是對稱的

    2.2 新節點:我是紅色的,我爹是紅色的,我叔叔也是紅色的

    • 把G節點設置為紅色
    • 把P節點設置為黑色
    • 把S節點設置為黑色
    • 把G節點設置為紅色
    • 把P節點設置為黑色
    • 把S節點設置為黑色

    這時候,如果G的父節點也是紅的,那么G的顏色翻轉的操作就會影響性質4,于是我們對G節點以及其父節點GP和父節點的兄弟節點GPS進行2.1所示的旋轉操作

    注意如果G的父節點GP為紅色,G父節點的兄弟節點GPS肯定不能為紅色,只能為黑色,因為在紅黑樹中,不可能出現出現深度小于樹的總深度且雙兄弟都為紅的情況,這種情況在其他的插入或刪除過程中已經消除了。

    GP剛好為根結點時,那么根據性質2,我們必須把GP重新設為黑色,那么樹的紅黑結構變為:黑黑紅。換句話說,從根結點到葉子結點的路徑中,黑色結點增加了。這也是唯一一種會增加紅黑樹黑色結點層數的插入情景。

    還有對稱的兩種情況,操作也是對稱的

    偽代碼

    RB-INSERT(T, z)//紅黑樹插入y = T.nilx = T.rootwhile x != T.nily = xif z.key<x.keyx = x.leftelse x = x.rightz.p = yif y == T.nilT.root = zelse if z.key < y.keyy.left = zelse y.right = zz.left = T.nilz.right = T.nilz.color = RED//對紅黑樹的性質進行恢復RB-INSERT-FIXUP(T, z)RB-INSERT-FIXUP(T, z)//插入紅色子節點,破壞了性質4時while z.p.color = RED//父節點為左子樹if z.p == z.p.p.left//獲取叔叔結點yy = z.p.p.right//叔叔結點為紅色if y.color = REDz.p.color = BLACKy.color = BLACKz.p.p.color = REDz = z.p.p//叔叔結點為黑色else //新插入的結點為父節點的右孩子,先來個父子調換,先進行一次左旋轉if z == z.p.rightz = z.pLEFT-ROTATE(T,z)//化成了叔叔結點黑色的一般情況z.p.color = BLACKz.p.p.color = REDRIGHT-ROTATE(T, z.p.p)//對稱情況else (same as then clause with "right" and "left" exchanged)T.root.color = BLACK

    難點來了,難點來了!!


    其實不難

    3.刪除操作

    刪除操作一直一來是樹這種ADT的難點所在

    一般二叉搜索樹的刪除操作:

    • 該節點為葉節點的情況:可以直接刪除,將其父節點的兒子指針設為Nil
    • 該節點只有一個非空子節點:可以直接刪除,將其父節點的兒子指針指向其唯一兒子
    • 該節點有兩個非空子節點:用該節點左子樹的最大節點或者右子樹的最小節點替換該節點,然后刪除對應的左子樹最大節點或者右子樹最小節點,最終可以回到前兩種情況。

    好,到這里你肯定還是明白的對吧

    現在考慮紅黑樹的刪除操作。

    注意:
    根據一般二叉搜索樹的刪除操作來看,我們要刪除的節點其實不一定是最終從圖中移出去的節點,稱最終從圖中移出去的節點為替代點,我們先從右子樹的最小節點(或左子樹的最大節點)找到我們的替代點,與刪除點的值交換,但是顏色都不變,然后再刪除替代點,然后對樹的性質進行恢復。而現在這些替代點都是一些樹的末節點(區別于葉節點,我們現在將Nil節點視為黑色葉節點),刪除操作便會簡化許多,并可以歸納為像插入那樣的幾個類別。當然了替代點和我們要刪除的點也有可能是同一點,但處理方法是一樣的。

    我們雖然刪除了替代點,但是我們對樹進行恢復時,還是會將該替代點放在樹中參與恢復,恢復完成后再移掉。

    在本文中,示例都默認是選擇右子樹的最小節點作為真正刪除點,也可以選擇左子樹的最大節點

    3.1替代點是紅色的

    直接從樹中去掉即可,不會影響紅黑樹的性質,算法直接結束

    不會出現替代點為紅色且有兒子為非葉子節點的情況,所以這種情況是最簡單的

    3.2替代點是黑色的

    替代點是黑色,那么刪除之后樹的性質就被破壞了,需要進行修復

    3.2.1 有一個兒子為且必須為紅色時

    當替代節點只有一個兒子且為紅色時
    直接用它的紅色兒子節點取代它,并將顏色改為黑色,這樣所有經過替代節點的路徑都將經過他的兒子,黑色高度不變。


    注意這跟上面圖不一樣,這張圖D節點是替代節點

    不可能存在只有一個兒子且兒子為黑色的情況,那樣本身就是不平衡的

    3.2.2 有兩個黑色兒子

    當替代點是黑色的且有兩個黑色兒子(可以為葉節點Nil)時,那他肯定有兄弟,那么又可以分為其他幾類

    • 替代點是黑色,其兄弟節點是紅色
    • 替代點是黑色,其兄弟節點是黑色
    3.2.2.1 替代點的兄弟節點是紅色

    • 將G節點也就是替代點的父節點設置為紅色,
    • 兄弟節點S設置為黑色
    • 然后進行向左單旋轉,

    現在可以直接刪掉D了嗎?(以下都默認標識D為替代點) 不行,tan90°\hspace4ex 不行,tan90\degreetan90°

    這個操作不改變任何路徑的黑色高度,這時候刪去D肯定會變的不平衡,我們只是把情況變為了兄弟節點為黑色的情況,也就是下面將要敘述的情況,我們接下來需要重新進入算法,進一步處理

    3.2.2.2 替代點的兄弟節點是黑色

    替代點D與其兄弟節點S都是黑色的,所以D的父節點顏色是不確定的,用綠色表示

    又分為以下幾種情況

    3.2.2.2.1 當兄弟節點的兩個兒子也都是黑色


    PS:C1、C2可為Nil

    • S節點顏色變為紅
    • G節點顏色變黑
    • 把G作為新的替代點進行下一輪操作

    假設G一開始是黑色的,這個操作過后,所有一開始經過S節點的路徑黑色高度-1,那么在刪除D節點后,所有經過D節點的路徑黑色高度也會-1,這棵子樹大家黑色高度都減一,結局竟該死的甜美,但是經過G的比不經過G的黑色高度減一了,所以再在G上重新平衡處理

    假設G一開始是紅色的,這個操作后,所有一開始經過S節點的路徑黑色高度不變,經過D的路徑黑色高度+1,那么在刪除D后,所有經過D節點的路徑黑色高度又變回來了,結局竟還是該死的甜美,經過G為根的子樹已經平衡了,再在G上重新平衡處理

    注意當G是樹的根時,就表示我們已經做完了,我們從所有路徑去除了一個黑色節點,所有性質在上溯過程中都保持著。

    3.2.2.2.2 當兄弟節點的左兒子是紅色的,右兒子是黑色

    • C1設置為黑色
    • S設置為紅色
    • 對S進行向右單旋轉

    這樣的操作不改變任何路徑的黑色高度,本來的平衡狀態不變,所以刪除D之后就破壞了原先的條件,還要進行自平衡變換,此時成了下面一種情況繼續處理

    3.2.2.2.3 當兄弟節點的右兒子是紅色的,左兒子隨意

    • 交換G和S的顏色
    • 設置兄弟節點的右兒子C2為黑色
    • 進行向左單旋轉

    該操作使所有變化前經過S節點的路徑黑色高度都不變,經過D的路徑黑色高度+1,在刪除D后,所有經過G節點的路徑都不變,達到平衡

    說白了刪除就是不斷遞歸變換直到滿足替代點的刪除條件。

    例子:刪除30根節點


    練習一下吧,這里有個在線紅黑樹工具,戳

    三:漸進邊界的證明

    包含n個內部節點的紅黑樹的高度是O(logn)O(logn)O(logn)

    定義:

    h(v)表示以節點v為根的子樹的高度。{\displaystyle h(v)}表示以節點{\displaystyle v}為根的子樹的高度。h(v)v
    bh(v)表示從v到子樹中任何葉子的黑色節點的數目{\displaystyle bh(v)}表示從{\displaystyle v}到子樹中任何葉子的黑色節點的數目bh(v)v
    (如果v是黑色則不計數它,也叫做黑色高度)。(如果{\displaystyle v}是黑色則不計數它,也叫做黑色高度)。v

    引理:以節點v為根的子樹有至少2bh(v)?1個內部節點。引理:以節點{\displaystyle v}為根的子樹有至少2^{bh(v)}-1個內部節點。v2bh(v)?1
    引理的證明(通過歸納高度):引理的證明(通過歸納高度):

    歸納假設:歸納假設:
    如果v的高度是零則它必定是NIL,因此bh(v)=0bh(v)=0。所以:2bh(v)?1=20?1=0如果v的高度是零則它必定是NIL,因此{\displaystyle bh(v)=0}{\displaystyle bh(v)=0}。所以:2^{{bh(v)}}-1=2^{{0}}-1=0vNILbh(v)=0bh(v)=02bh(v)?1=20?1=0

    如果h(v)=k,有2bh(v)?1個內部節點成立如果h(v)=k,有2^{bh(v)}-1個內部節點成立h(v)=k2bh(v)?1
    于是h(v′)=k+1于是h(v')=k+1h(v)=k+1
    因為v′有h(v′)>0所以它是個內部節點。同樣的它有的兩個兒子,其黑色高度要么是bh(v′)要么是bh(v′)?1(依據v′是紅色還是黑色)。通過歸納假設每個兒子都有至少2bh(v′)?1?1個內部接點,所以v′有:因為v'有h(v')>0 \\所以它是個內部節點。同樣的它有的兩個兒子,其黑色高度要么是bh(v')要么是bh(v')-1(依據v'是紅色還是黑色)。通過歸納假設每個兒子都有至少2^{{bh(v')-1}}-1個內部接點,所以v'有:vh(v)>0bh(v)bh(v)?1v2bh(v)?1?1v
    2bh(v′)?1?1+2bh(v′)?1?1+1=2bh(v′)?1個內部節點。2^{bh(v')-1}-1+2^{bh(v')-1}-1+1=2^{bh(v')}-1個內部節點。2bh(v)?1?1+2bh(v)?1?1+1=2bh(v)?1

    使用這個引理我們現在可以展示出樹的高度是對數性的。因為在從根到葉子的任何路徑上至少有一半的節點是黑色(根據紅黑樹性質4),根的黑色高度至少是h(root)2通過引理我們得到:使用這個引理我們現在可以展示出樹的高度是對數性的。\\ 因為在從根到葉子的任何路徑上至少有一半的節點是黑色(根據紅黑樹性質4),\\根的黑色高度至少是 {\frac {h(root)}{2}}通過引理我們得到:使(4)2h(root)?

    n?2h(root)2?1?log?(n+1)?h(root)2?h(root)?2log?(n+1)n?2h(root)2?1?log?(n+1)?h(root)2?h(root)?2log?(n+1){\displaystyle n\geqslant 2^{\frac {h(root)}{2}}-1\leftrightarrow \;\log {(n+1)}\geqslant {\frac {h(root)}{2}}\leftrightarrow \;h(root)\leqslant 2\log {(n+1)}}n\geqslant 2^{{{\frac {h(root)}{2}}}}-1\leftrightarrow \;\log {(n+1)}\geqslant {\frac {h(root)}{2}}\leftrightarrow \;h(root)\leqslant 2\log {(n+1)}n?22h(root)??1?log(n+1)?2h(root)??h(root)?2log(n+1)n?22h(root)??1?log(n+1)?2h(root)??h(root)?2log(n+1)

    因此根的高度是O(log?n)因此根的高度是{\displaystyle {\text{O}}(\log n)}O(logn)

    總結

    以上是生活随笔為你收集整理的红黑树,看不懂你找我的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。