1. 程式人生 > >紅黑樹插入、刪除、查詢演算法學習

紅黑樹插入、刪除、查詢演算法學習

紅黑樹(red-black tree)是許多“平衡”搜尋樹中的一種,可以保證在最壞情況下基本動態集合操作的時間複雜度為O(lgn)。

一、紅黑樹的性質

紅黑樹是一棵二叉搜尋樹,但在每個結點上增加一個儲存位表示結點的顏色,可以是Red或Black。通過對任何一條從根到葉子的路徑上各個結點著色方式的限制,紅黑樹確保沒有一條路徑會比其他路徑長出2倍,因而是接近平衡的。樹中每個結點內含五個域,color,key,lchild,rchild,parent。如果相應的指標域沒有,則設為NIL。
一棵紅黑是滿足以下性質的二叉搜尋樹:
1. 每個結點要麼是紅色的,要麼是黑色的。
2. 根結點是黑色的。


3. 每個葉結點(NIL)是黑色的。
4. 如果一個結點是紅色色的,那麼它的兩個子結點都是黑色的。
5. 對每個結點,從該結點到其子結點的簡單路徑上,均包含相同數目的黑色結點。

為了便於處理紅黑樹程式碼中的邊界條件,使用一個哨兵來代表NIL。哨兵T.Nil是一個與書中普通結點有相同屬性的物件,他的color屬性是BLACK,其他屬性可以設為任意值。
0

紅黑樹結構描述如下:

typedef int KeyType;        //假定關鍵字型別為整數
typedef enum {RED = 1,BLACK = 0}  Color;  //定義顏色型別
typedef struct
node //結點型別 { KeyType key; //關鍵字項 Color color; //顏色 struct node *lchild, *rchild, *parent; //左右孩子和雙親 } *pRBTNode, RBTNode; typedef struct Tree //紅黑樹型別 { pRBTNode Root; //根結點 pRBTNode Nil; //哨兵 }*RBTree,RBTreeNode;

二、旋轉

當在對紅黑樹進行插入和刪除等操作時,對樹做了修改,可能會違背紅黑樹的性質。為了保持紅黑樹的性質,可以通過對樹進行旋轉

,即修改樹中某些結點的顏色及指標結構,以保持它特有的性質。
有兩種旋轉方式:左旋和右旋,如下圖:

當在某個結點x上做左旋操作時,假設它的右孩子y不是T->Nil,x可以為樹內任意右孩子而不是T->Nil的結點。左旋以x到y之間的鏈為“支軸”進行,它使y成為該子樹新的根結點,x成為y的左孩子,y的左孩子b成為x的右孩子。
C語言演算法實現如下:

void LeftRotate(RBTree T, pRBTNode x) //左旋轉
{
    pRBTNode y;
    y = x->rchild;
    x->rchild = y->lchild;
    if (y->lchild != T->Nil)
        y->lchild->parent = x;
    if (x != T->Nil)
        y->parent = x->parent;
    if (x->parent == T->Nil)
        T->Root = y;
    else
    {
        if (x->parent->lchild == x)
            x->parent->lchild = y;
        else
            x->parent->rchild = y;
    }
    y->lchild = x;
    if (x != T->Nil)
        x->parent = y;
}

右旋與左旋操作程式碼對稱,在旋轉操作中只有指標改變,其他所有屬性都保持不變。

三、插入

向一棵含有n個結點的紅黑樹中插入一個新結點的操作可以在O(lgn)時間內完成。

void RBTreeInsert(RBTree T, KeyType key)   //插入演算法
{
    pRBTNode x,y,z;
    x = T->Root;
    y = T->Nil;
    z = (pRBTNode)malloc(sizeof(RBTNode));
    z->color = RED;
    z->key = key;
    z->parent = NULL;
    z->lchild = NULL;
    z->rchild = NULL;
    while (x != T->Nil)
    {
        y = x;
        if (z->key<x->key)
            x = x->lchild;
        else x = x->rchild;
    }
    z->parent = y;
    if (y != T->Nil)
    {
        if (z->key>y->key)
            y->rchild = z;
        else if (z->key<y->key)
            y->lchild = z;
    }
    else
    {
        T->Root = z;
    }
    z->lchild = T->Nil;
    z->rchild = T->Nil;

    RBTreeInsertFixup(T, z);
}

每次插入一個結點,都將其著為紅色,但可能違反紅黑性質,為此,呼叫RBTreeInsertFixup來保持紅黑性質

void RBTreeInsertFixup(RBTree T, pRBTNode z)   //重新著色並旋轉結點
{
    pRBTNode y;
    while ((z->parent != NULL) && (z->parent->color == RED))
    {
        if (z->parent == z->parent->parent->lchild)
        {
            y = z->parent->parent->rchild;
            if ((y != NULL) && (y->color == RED))
            {
                z->parent->color = BLACK;          //情況1
                y->color = BLACK;                  //情況1
                z->parent->parent->color = RED;    //情況1
                z = z->parent->parent;             //情況1
            }
            else
            {
                if (z == z->parent->rchild)
                {
                    z = z->parent;                //情況2
                    LeftRotate(T,z);              //情況2
                }
                z->parent->color = BLACK;         //情況3
                z->parent->parent->color = RED;   //情況3
                RightRotate(T, z->parent->parent);//情況3
            }
        }
        else
        {
            y = z->parent->parent->lchild;
            if ((y != NULL) && (y->color == RED))
            {
                z->parent->color = BLACK;
                y->color = BLACK;
                z->parent->parent->color = RED;
                z = z->parent->parent;
            }
            else
            {
                if (z == z->parent->lchild)
                {
                    z = z->parent;
                    RightRotate(T, z);
                }
                z->parent->color = BLACK;
                z->parent->parent->color = RED;
                LeftRotate(T, z->parent->parent);
            }
        }
    }
    T->Root->color = BLACK;
    T->Nil->color = BLACK;</span><span style="font-size:24px;">
}

在對紅黑樹進行插入操作時,我們一般總是插入紅色的結點,因為這樣可以在插入過程中儘量避免對樹的調整。如果插入的結點是根結點,性質2會被破壞,如果插入結點的父結點是紅色,則會破壞性質4,其他性質不會被破壞。
如果插入節點的父親為黑色,則不需要進行調整,若為紅色,有三種情況需要討論。

情況1:z的叔結點y是紅色的


插入後的結點是z,由於z和它的父結點z.parent都是紅色的,違反了性質4,。由於z的叔結點y是紅色的,可以應用程式中的情況1。同時改變父、叔節點顏色為黑色,並將爺爺節點置紅,指標z沿樹上升,這樣在這個區域性範圍內,保持黑色平衡。如果z此時為根,則置z為黑色,調整結束,否則相當於又插入了一個紅色節點,進行新一輪迭代,得到情況2。

情況2:z的叔結點y是黑色的且z是一個右孩子。


再一次z及其父結點都為紅色,但z的叔結點是黑色的,因為z是z.parent的右孩子,可以應用情況2。在執行一次左旋後,得到結果如情況3所示。

情況3:z的叔結點y是黑色的且z是一個左孩子。


現在,z是其父結點的左孩子,可以應用情況3,重新著色並執行一次右旋得到一棵合法的紅黑樹。
合法紅黑樹:

四、刪除

刪除一個結點要花費O(lgn)時間,與插入相比,刪除操作要複雜些。

第一:先看最簡單情況,即刪除紅色節點。刪除紅色節點,不影響紅黑樹平衡性質,只需要刪除紅色節點,不需要進行調整,因為不影響紅黑樹的性質。 黑色節點沒有增多也沒有減少。如圖:

注意:以下幾種單支情況破壞了紅黑樹的平衡狀態。在平衡的紅黑樹中不可能出現。所以,平衡狀態下紅黑樹要麼是單支黑-紅,要麼有兩個子節點。

第二:刪除單支黑節點

第三:若刪除節點有左右兩個兒子,即左右子樹。需要按照二叉搜尋樹的刪除規律,從右子樹中找最小的替換刪除節點(該節點至多有一個右子樹,無左子樹),將該節點記為y, 刪除節點記為z,y的右子樹記為x(可能為空)。

刪除規則:用y替換z,交換y與z顏色,同時y = z,改變y的指向,讓y指向最終刪除節點。為了便於理解,可以先這樣假設:將y與z的資料交換,但顏色不交換,這樣,實際相當於將刪除轉移到了y節點,而z處保持原先狀態(處於平衡)。此時可以完全不用了理會z節點,直接刪除y節點即可。因為y最多隻有一個右子樹,無左子樹,這便轉移到了“第二”。

對於刪除y節點,有幾種考慮:
1. 若y為紅色,則這種情況如上述”第一“所述,並不影響平衡性。
2. 若y為黑色,則刪除y後,x替換了y的位置,這樣x子樹相對於兄弟節點w為根的子樹少了一個黑節點,影響平衡,需要進行調整。
剩下的調整工作就是將x子樹中找一合適紅色節點,將其置黑,使得x子樹與w子樹達到平衡。若x為紅色,直接將x置為黑色,即可達到平衡。

若x為黑色,則分下列幾種情況:
情況1: x的兄弟w為紅色,則w的子樹必然全黑,w父親p也為黑。改變p與w的顏色,同時對p做一次左旋,這樣就將情況1轉變為情況2,3,4的一種。

情況2: x的兄弟w為黑色,x與w的父親顏色可紅可黑。因為x子樹相對於其兄弟w子樹少一個黑色節點,可以將w置為紅色,這樣,x子樹與w子樹黑色節點一致,保持了平衡。new x為x與w的父親。new x相對於它的兄弟節點new w少一個黑色節點。如果new x為紅色,則將new x置為黑,則整棵樹平衡。

情況3: w為黑色,w左孩子紅色,右孩子黑色。 交換w與左孩子的顏色,對w進行右旋。轉換為情況4。
這裡寫圖片描述
情況4: w為黑色,右孩子為紅色。交換w與父親p顏色,同時對p做左旋。這樣左邊缺失的黑色就補回來了,同時,將w的右孩子置黑,這樣左右都達到平衡。

情況2是最好理解的,減少右子樹的一個黑色節點,使x與w平衡,將不平衡點上移至x與w的父親,進行下一輪迭代。情況1:如果w為紅色,通過旋轉,轉成成情況1,2,3進行處理。而情況3轉換為情況4進行處理。也就是說,情況4是最接近最終解的情況。情況4:右兒子是紅色節點,那麼將缺失的黑色交給右兒子,通過旋轉,達到平衡。

void RBTreeTransplant(RBTree T, pRBTNode u, pRBTNode v)   //v替換u
{
    if (u->parent == T->Nil)
        T->Root = v;
    else if (u == u->parent->lchild)
        u->parent->lchild = v;
    else u->parent->rchild = v;
    v->parent = u->parent;
}
void RBTreeDelete(RBTree T, pRBTNode z)    //刪除
{
    pRBTNode x, y;
    Color y_original_color;
    y = z;
    y_original_color = y->color;
    if (z->lchild == T->Nil)
    {
        x = z->rchild;
        RBTreeTransplant(T, z, z->rchild);
    }
    else if (z->rchild == T->Nil)
    {
        x = z->lchild;
        RBTreeTransplant(T, z, z->lchild);
    }
    else
    {
        y = TreeMin(T, z->rchild);
        y_original_color = y->color;
        x = y->rchild;
        if (y->parent == z)
            x->parent = y;
        else
        {
            RBTreeTransplant(T, y, y->rchild);
            y->rchild = z->rchild;
            y->rchild->parent = y;
        }
        RBTreeTransplant(T, z, y);
        y->lchild = z->lchild;
        y->lchild->parent = y;
        y->color = z->color;
    }
    if (y_original_color = BLACK)
        RBTreeDeleteFixup(T, x);
    free(y);
}
void RBTreeDeleteFixup(RBTree T, pRBTNode x)  //輔助刪除過程
{
    pRBTNode w;
    while ((x != T->Root) && (x->color == BLACK))
    {
        if (x == x->parent->lchild)
        {
            w = x->parent->rchild;
            if (w->color == RED)
            {
                w->color = BLACK;
                x->parent->color = RED;
                LeftRotate(T, x->parent);
                w = x->parent->rchild;
            }
            if (w->lchild->color == BLACK && w->rchild->color == BLACK)
            {
                w->color = RED;
                x = x->parent;
            }
            else
            {
                if (w->rchild->color == BLACK)
                {
                    w->lchild->color = BLACK;
                    w->color = RED;
                    RightRotate(T, w);
                    w = x->parent->rchild;
                }
                w->color = w->parent->color;
                x->parent->color = BLACK;
                w->rchild->color = BLACK;
                LeftRotate(T, x->parent);
                x = T->Root;
            }
        }
        else
        {
            w = x->parent->lchild;
            if (w->color == RED)
            {
                w->color = BLACK;
                x->parent->color = RED;
                RightRotate(T, x->parent);
                w = x->parent->lchild;
            }
            if (w->rchild->color == BLACK&&w->lchild->color == BLACK)
            {
                w->color = RED;
                x = x->parent;
            }
            else
            {
                if (w->lchild->color == BLACK)
                {
                    w->rchild->color = BLACK;
                    w->color = RED;
                    LeftRotate(T, w);
                    w = x->parent->lchild;
                }
                w->color = w->parent->color;
                x->parent->color = BLACK;
                w->lchild->color = BLACK;
                RightRotate(T, x->parent);
                x = T->Root;
            }
        }
    }
    x->color = BLACK;
}

五、完整的C語言程式

寫一個完整的C程式,測試插入,刪除等演算法。執行程式,根據提示進行相應的操作。

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define MAXSIZE 1000

typedef int KeyType;        //假定關鍵字型別為整數
typedef enum {RED = 1,BLACK = 0}  Color;  //定義顏色型別
typedef struct node         //結點型別
{
    KeyType key;       //關鍵字項
    Color color;          //顏色
    struct node *lchild, *rchild, *parent; //左右孩子和雙親
} *pRBTNode, RBTNode;

typedef struct Tree    //紅黑樹型別
{
    pRBTNode Root;     //根結點
    pRBTNode Nil;      //哨兵

}*RBTree,RBTreeNode;
/*-------------------------------------------------------*/
RBTree InitRBTree();   //初始化
void LeftRotate(RBTree T, pRBTNode x);     //左旋轉
void RightRotate(RBTree T, pRBTNode x);     //右旋轉
void RBTreeInsertFixup(RBTree T, pRBTNode z);   //重新著色並旋轉結點
void RBTreeInsert(RBTree T, KeyType key);   //插入演算法
void InorderTreeWalk_Recursive(pRBTNode t);     //中序遍歷的遞迴演算法
void InorderTreeWalk_NonRecursive(RBTree T);     //中序遍歷的非遞迴演算法
void RBTreeTransplant(RBTree T, pRBTNode u, pRBTNode v);  //v替換u
pRBTNode TreeMin(RBTree T, pRBTNode t);     //查詢關鍵字最小的結點
pRBTNode TreeMax(RBTree T, pRBTNode t);     //查詢關鍵字最大的結點
void RBTreeDeleteFixup(RBTree T, pRBTNode x);  //輔助刪除過程
void RBTreeDelete(RBTree T, pRBTNode z);    //刪除
pRBTNode SearchNodeByKey(RBTree T, KeyType key);  //根據關鍵字查詢結點
RBTree CreateRandom();   //隨機生成一棵紅黑樹
void menu();     //選單
/*-------------------------------------------------------*/

int main()
{
    RBTree Tree = NULL;
    KeyType key;
    pRBTNode x;
    char ch;
    menu();
    while (1)
    {
        printf(">");
        ch = getchar();
        switch (ch)
        {
        case '0':
        {
            menu();
            break;
        }
        case '1':
        {
            Tree = InitRBTree();
            break;
        }
        case '2':
        {
            if (Tree == NULL)
            {
                printf("The tree is null.Please Create it first!\n");
                break;
            }
            printf("Enter key:");
            scanf("%d", &key);
            RBTreeInsert(Tree, key);
            printf("Insert Success!\n");
            break;
        }
        case '3':
        {
            if (Tree == NULL)
            {
                printf("The tree is null.Please Create it first!\n");
                break;
            }
            printf("Enter the key you want to delete:");
            scanf("%d", &key);
            x = SearchNodeByKey(Tree, key);
            if (x != Tree->Nil)
            {
                RBTreeDelete(Tree, x);
                printf("Delete Success!\n");
            }
            else 
                printf("No this key.Delete failed! \n");
            break;
        }
        case '4':
        {
            if (Tree == NULL)
            {
                printf("The tree is null.Please Create it first!\n");
                break;
            }
            x = TreeMin(Tree, Tree->Root);
            printf("the min key:%d\n",x->key);
            break;
        }
        case '5':
        {
            if (Tree == NULL)
            {
                printf("The tree is null.Please Create it first!\n");
                break;
            }
            x = TreeMax(Tree, Tree->Root);
            printf("the max key:%d\n", x->key);
            break;
        }
        case '6':
        {
            if (Tree == NULL)
            {
                printf("The tree is null.Please Create it first!\n");
                break;
            }

            InorderTreeWalk_Recursive(Tree->Root);
            printf("\n");
            break;
        }
        case '8':
        {
            Tree = CreateRandom();
            break;
        }
        case 'e':
            return;
        case '\n':
            break;
        default:
            menu();
            break;
        }
    }
    return 0;
}

/*-------------------------------------------------------*/
void menu()     //選單
{
    printf("*--------------Red-Black Tree-----------------*\n");
    printf("1----Create RBTree.        4----Minimum Node.\n");
    printf("2----Insert Node.          5----Maximum Node.\n");
    printf("3----Delete Node.          6----Print RBTree.\n");
    printf("8----Create RBtree Random(100000 Nodes)\n");
    printf("0----Help.                 e----Exit\n");
    printf("*---------------------------------------------*\n");
}
/*-------------------------------------------------------*/
RBTree InitRBTree()   //初始化
{
    RBTree T = (RBTree)malloc(sizeof(RBTreeNode));
    T->Nil = (pRBTNode)malloc(sizeof(RBTNode));
    T->Root = (pRBTNode)malloc(sizeof(RBTNode));
    T->Nil->color = BLACK;
    T->Nil->lchild = NULL;
    T->Nil->rchild = NULL;
    T->Nil->parent = NULL;
    T->Nil->key = -1;
    T->Root = T->Nil;
    printf("Enter the number of integers(EndFlag:0):\n");
    KeyType key, EndFlag = 0;
    scanf("%d", &key);
    while (key != EndFlag)
    {
        RBTreeInsert(T, key);
        scanf("%d", &key);
    }
    return T;
}
/*-------------------------------------------------------*/
RBTree CreateRandom()   //隨機生成一棵紅黑樹
{
    RBTree T = (RBTree)malloc(sizeof(RBTreeNode));
    T->Nil = (pRBTNode)malloc(sizeof(RBTNode));
    T->Root = (pRBTNode)malloc(sizeof(RBTNode));
    T->Nil->color = BLACK;
    T->Nil->lchild = NULL;
    T->Nil->rchild = NULL;
    T->Nil->parent = NULL;
    T->Nil->key = -1;
    T->Root = T->Nil;
    KeyType key;
    int i = 0;
    srand(time(NULL));
    while (i++ <100000)
    {
        key = rand()%100000 + 1; //生成一個1-32768之間的數字
        RBTreeInsert(T, key);
    }
    return T;
}
/*-------------------------------------------------------*/
void LeftRotate(RBTree T, pRBTNode x) //左旋轉
{
    pRBTNode y;
    y = x->rchild;
    x->rchild = y->lchild;
    if (y->lchild != T->Nil)
        y->lchild->parent = x;
    if (x != T->Nil)
        y->parent = x->parent;
    if (x->parent == T->Nil)
        T->Root = y;
    else
    {
        if (x->parent->lchild == x)
            x->parent->lchild = y;
        else
            x->parent->rchild = y;
    }
    y->lchild = x;
    if (x != T->Nil)
        x->parent = y;
}
/*-------------------------------------------------------*/
void RightRotate(RBTree T, pRBTNode x)     //右旋轉
{
    pRBTNode  y;
    y = x->lchild;
    x->lchild = y->rchild;
    if (y->rchild != T->Nil)
        y->rchild->parent = x;
    if (x != T->Nil)
        y->parent = x->parent;
    if (x->parent == T->Nil)
        T->Root = y;
    else
    {
        if (x->parent->lchild == x)
            x->parent->lchild = y;
        else
            x->parent->rchild = y;
    }
    y->rchild = x;
    if (x != T->Nil)
        x->parent = y;
}
/*-------------------------------------------------------*/
void RBTreeInsertFixup(RBTree T, pRBTNode z)   //重新著色並旋轉結點
{
    pRBTNode y;
    while ((z->parent != NULL) && (z->parent->color == RED))
    {
        if (z->parent == z->parent->parent->lchild)
        {
            y = z->parent->parent->rchild;
            if ((y != NULL) && (y->color == RED))
            {
                z->parent->color = BLACK;          //情況1
                y->color = BLACK;                  //情況1
                z->parent->parent->color = RED;    //情況1
                z = z->parent->parent;             //情況1
            }
            else
            {
                if (z == z->parent->rchild)
                {
                    z = z->parent;                //情況2
                    LeftRotate(T,z);              //情況2
                }
                z->parent->color = BLACK;         //情況3
                z->parent->parent->color = RED;   //情況3
                RightRotate(T, z->parent->parent);//情況3
            }
        }
        else
        {
            y = z->parent->parent->lchild;
            if ((y != NULL) && (y->color == RED))
            {
                z->parent->color = BLACK;
                y->color = BLACK;
                z->parent->parent->color = RED;
                z = z->parent->parent;
            }
            else
            {
                if (z == z->parent->lchild)
                {
                    z = z->parent;
                    RightRotate(T, z);
                }
                z->parent->color = BLACK;
                z->parent->parent->color = RED;
                LeftRotate(T, z->parent->parent);
            }
        }
    }
    T->Root->color = BLACK;
    T->Nil->color = BLACK;
}
/*-------------------------------------------------------*/
void RBTreeInsert(RBTree T, KeyType key)   //插入演算法
{
    pRBTNode x,y,z;
    x = T->Root;
    y = T->Nil;
    z = (pRBTNode)malloc(sizeof(RBTNode));
    z->color = RED;
    z->key = key;
    z->parent = NULL;
    z->lchild = NULL;
    z->rchild = NULL;
    while (x != T->Nil)
    {
        y = x;
        if (z->key<x->key)
            x = x->lchild;
        else x = x->rchild;
    }
    z->parent = y;
    if (y != T->Nil)
    {
        if (z->key>y->key)
            y->rchild = z;
        else if (z->key<y->key)
            y->lchild = z;
    }
    else
    {
        T->Root = z;
    }
    z->lchild = T->Nil;
    z->rchild = T->Nil;

    RBTreeInsertFixup(T, z);
}
/*-------------------------------------------------------*/
void InorderTreeWalk_Recursive(pRBTNode t)     //中序遍歷的遞迴演算法
{
    if (t->key != -1)
    {
        InorderTreeWalk_Recursive(t->lchild);   //訪問左子樹
        printf("%d ", t->key);        //訪問結點
        InorderTreeWalk_Recursive(t->rchild);   //訪問右子樹
    }
}
/*-------------------------------------------------------*/
void InorderTreeWalk_NonRecursive(RBTree T)     //中序遍歷的非遞迴演算法
{
    int top = -1;
    pRBTNode Stack[MAXSIZE];
    pRBTNode x = T->Root;
    while (top != -1 || x != T->Nil)
    {
        while (x != T->Nil)
        {
            if (top == MAXSIZE - 1)
            {
                printf("overflow!!\n");
                return;
            }
            else
            {
                Stack[++top] = x;
                x = x->lchild;
            }
        }
        x = Stack[top--];
        printf("%d ", x->key);
        x = x->rchild;
    }
}
/*-------------------------------------------------------*/
void RBTreeTransplant(RBTree T, pRBTNode u, pRBTNode v)   //v替換u
{
    if (u->parent == T->Nil)
        T->Root = v;
    else if (u == u->parent->lchild)
        u->parent->lchild = v;
    else u->parent->rchild = v;
    v->parent = u->parent;
}
/*-------------------------------------------------------*/
pRBTNode TreeMin(RBTree T, pRBTNode t)     //查詢關鍵字最小的結點
{
    pRBTNode x = t;
    while (x->lchild != T->Nil)
        x = x->lchild;
    return x;
}
/*-------------------------------------------------------*/
pRBTNode TreeMax(RBTree T, pRBTNode t)     //查詢關鍵字最大的結點
{
    pRBTNode x = t;
    while (x->rchild != T->Nil)
        x = x->rchild;
    return x;
}
/*-------------------------------------------------------*/
void RBTreeDelete(RBTree T, pRBTNode z)    //刪除
{
    pRBTNode x, y;
    Color y_original_color;
    y = z;
    y_original_color = y->color;
    if (z->lchild == T->Nil)
    {
        x = z->rchild;
        RBTreeTransplant(T, z, z->rchild);
    }
    else if (z->rchild == T->Nil)
    {
        x = z->lchild;
        RBTreeTransplant(T, z, z->lchild);
    }
    else
    {
        y = TreeMin(T, z->rchild);
        y_original_color = y->color;
        x = y->rchild;
        if (y->parent == z)
            x->parent = y;
        else
        {
            RBTreeTransplant(T, y, y->rchild);
            y->rchild = z->rchild;
            y->rchild->parent = y;
        }
        RBTreeTransplant(T, z, y);
        y->lchild = z->lchild;
        y->lchild->parent = y;
        y->color = z->color;
    }
    if (y_original_color = BLACK)
        RBTreeDeleteFixup(T, x);
    free(y);
}
/*-------------------------------------------------------*/
void RBTreeDeleteFixup(RBTree T, pRBTNode x)  //輔助刪除過程
{
    pRBTNode w;
    while ((x != T->Root) && (x->color == BLACK))
    {
        if (x == x->parent->lchild)
        {
            w = x->parent->rchild;
            if (w->color == RED)
            {
                w->color = BLACK;
                x->parent->color = RED;
                LeftRotate(T, x->parent);
                w = x->parent->rchild;
            }
            if (w->lchild->color == BLACK && w->rchild->color == BLACK)
            {
                w->color = RED;
                x = x->parent;
            }
            else
            {
                if (w->rchild->color == BLACK)
                {
                    w->lchild->color = BLACK;
                    w->color = RED;
                    RightRotate(T, w);
                    w = x->parent->rchild;
                }
                w->color = w->parent->color;
                x->parent->color = BLACK;
                w->rchild->color = BLACK;
                LeftRotate(T, x->parent);
                x = T->Root;
            }
        }
        else
        {
            w = x->parent->lchild;
            if (w->color == RED)
            {
                w->color = BLACK;
                x->parent->color = RED;
                RightRotate(T, x->parent);
                w = x->parent->lchild;
            }
            if (w->rchild->color == BLACK&&w->lchild->color == BLACK)
            {
                w->color = RED;
                x = x->parent;
            }
            else
            {
                if (w->lchild->color == BLACK)
                {
                    w->rchild->color = BLACK;
                    w->color = RED;