红黑树(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;
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;
}
/*-------------------------------------------------------*/
pRBTNode SearchNodeByKey(RBTree T, KeyType key) //根据关键字查找结点
{
pRBTNode x = T->Root;
while (x != T->Nil && key != x->key)
{
if (key < x->key)
x = x->lchild;
else
x = x->rchild;
}
return x;
}
程序可以运行,但有时候会出错,太累了,这个bug先不找了。