1. 程式人生 > 資訊 >完美世界仙俠遊戲《誅仙世界》實機視訊曝光:採用 UE4 引擎,擁有晝夜迴圈和四季交替

完美世界仙俠遊戲《誅仙世界》實機視訊曝光:採用 UE4 引擎,擁有晝夜迴圈和四季交替

平衡樹:
  1. AVL 樹
  2. 2-3 樹
  3. 2-3-4 樹
  4. 紅黑樹
  5. B-樹
紅黑樹的性質: 1.每個結點要麼是黑色或者紅色。 2.根結點和葉節點(nil)是黑色。 3.如果一個結點是紅色的,則它的父結點和兩個子結點都是黑色的。 4.對每個結點,從該結點到其所有後代葉結點的簡單路徑上,均包含相同數目的黑色結點,稱為黑高。bh(x) 推論: 1.一棵有n個結點的紅黑樹高度至多為2lg(n + 1)。
  • 插入操作
  關鍵:使用recolor 和 rotation 操作維持RBT的紅黑屬性。   1. case1: x的叔結點y是紅色的。   2. case2: x的叔結點y是黑色的且x是一個右孩子。   3. case3: x的叔結點y是黑色的且x是一個左孩子。   一次插入操作時間複雜度:O(lgn)
RB-Insert(T, z):
    y = T.nil.                            // 二叉搜尋樹的插入操作
    x = T.root
    while x != T.nil:
        y = x
        if z.key < x.key:
            x = x.left
        else:
            x = x.right
    z.p = y
    if y == T.nil:
        T.root = z
    else if z.key < y.key:
        y.left = z
    else:
        y.right = z
    z.left = T.nil
    z.right = T.nil
    z.color = RED
    RB-INSERT-FIXUP(T, z)
 
RB-INSERT-FIXUP(T, z):
    while z != T.root and z.p.color == RED:
        if z.p == z.p.p.left:
            y = z.p.p.right
            if y.color = RED:            // case1: 將 z 祖父結點的Black屬性下移給其子節點
                z.p.color = BLACK        // 因為 z.p 和 y 都是Red屬性,所以對稱轉移不會改變RBT的屬性
                y.color = BLACK
                z.p.p.color = RED
                z = z.p.p
            else if z == z.p.right:      // case2: z 是右子結點,對x父結點左旋將 z 和 z.p 放在一條直線上
                    z = z.p
                    LEFT_ROTATION(T, z)
                z.p.color = BLACK        // case3: 可能由case2轉移得到,先重新著色,再對 z 祖父結點右旋將 z 的父結點作為新子樹的根結點 
                z.p.p.color = RED
                RIGHT_ROTATION(T, z.p.p)
        else:                           // 對稱如果 z 父結點是右子樹結點,有3種case
            // same as above with “right” and “left” exchanged
    T.root.color = BLACK
  • 刪除操作
  恢復紅黑樹屬性。   1. case1: x 的兄弟結點 w 是紅色的。   2. case2:x 的兄弟結點 w 是黑色的,而且 w 的兩個子結點都是黑色的。   3.case3:x 的兄弟結點 w 是黑色的,w 的左子結點是紅色的,右子結點是黑色的。   4. case4:x 的兄弟結點 w 是黑色的,w 的右子結點是紅色的。   一次刪除操作時間複雜度:O(lgn)
RB-TRANSPLANT(T, u, v):       // 用子樹 v 代替 u
    if u.p == T.nil:
        T.root = v
    else if u == u.p.left:
        u.p.left = v
    else:
        u.p.right = v
    v.p = u.p
 
RB- DELETE(T, z):
    y = z
    y_original_color = y.color
    if z.left = T.nil:                // case1: 被刪除結點只有右子結點
        x = z.right
        RB-TRANSPLANT(T, y, x)        // 將 x 移到 y 的原始位置
    else if z.right = T.nil:          // case2: 被刪除結點只有左子結點
        x = z.left
        RB-TRANSPLANT(T, y, x) 
    else:                            // case3: 被刪除結點有左右子結點
        y = TREE-MINIMUM(z.right)    // 找到後繼結點 y
        y_original_color = y.color
        x = y.right
        if y.p == z:                 // 其他情況:x.p = y.p    
            x.p = y
        else:
            RB-TRANSPLANT(T, y, x)   // 將 x 移到 y 的原始位置
            y.right = z.right        // 原 z 的左右子結點要轉移成 y 的左右子結點
            y.right.p = y
        RB-TRANSPLANT(T, z, y)       // 將 y 移到 z 的原始位置
        y.left = z.left              // 原 z 的左右子結點要轉移成 y 的左右子結點
        y.left.p = y
        y.color = z
    if y-original-color == BLACK:    // 如果刪除/移動的是紅色結點不影響RBT樹的紅黑屬性
        RB-DELETE-FIXUP(T, x)        // 否則要維護樹的紅黑屬性
 
 
/*
如果 y.color是黑色,則上述刪除操作可能造成3個問題:
1.如果 y 是原來的根結點,而 y 的一個紅色孩子成為新的根結點,違反性質2.
2.如果 x 和 x.p (原 y.p)都是紅色,違反性質3.
3.在樹中移動 y 結點將導致先前包含 y (之後不包含)的任何簡單路徑上黑結點個數少1,因此 y 的任何子線不滿足性質4.
改正這一問題的辦法是:將現在佔有 y 原來位置的結點 x 視為還有一重額外的黑色。即:如果將任意包含結點 x 的簡單路徑上黑結點個數加1,則在這種假設下,性質4成立。當黑結點 y 刪除或移動時,將其黑色屬性“下推”給 x。現在的 x 是雙重黑色或者紅黑色,分別給包含 x 的簡單路徑上黑結點數貢獻2或1。x 的color屬性仍然是RED(如果 x 是紅黑色的)或者BLACK(如果 x 是雙重黑色的)。換而言之,結點額外的黑色是針對 x 結點的,而不是反映在它的color屬性上。
*/
 
RB-DELETE-FIXUP(T, x):
    while x != T.root and x.color == BLACK:
        if x == x.p.left:                   
            w = x.p.right
            if w.color == RED:           // case1: 將 x 父結點左旋,轉移到case2
                w.color = BLACK
                x.p.color = RED
                LEFT-ROTATION(T, x.p)
                w = x.p.right
            if w.left.color == BLACK and w.right.color == BLACK:  // case2
                w.color = RED
                x = x.p
            else if w.right.color == BLACK:       // case3
                    w.left.color = BLACK
                    w.color = RED
                    RIHGT-ROTATION(T, w)
                    w = x.p.right
                w.color = x.p.color              // case4
                x.p.color = BLACK
                w.right.color = BLACK
                LEFT-ROTATION(T, x.p)
                x = T.root
        else:
            // same as above with “right” and “left” exchanged
    x.color = BLACK           
  • 應用
(參看《演算法導論》)