紅黑樹插入、刪除、查詢演算法學習
紅黑樹(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,其他屬性可以設為任意值。
紅黑樹結構描述如下:
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;