[算法]红黑树的实现代码(修订版)
2008-11-10补充---这份代码仍然是有问题的, 再次的修正版本在这里:
http://www.cppblog.com/converse/archive/2008/11/10/66530.html
在之前,我曾经给出过一份红黑树的实现代码,很多人提出异议,说是代码有问题,我曾经做过一些测试,貌似都没有出错,因为这份代码是在我学习红黑树之后很久才贴出来的,所以后来没有再仔细看这份代码。
最近,因为工作上的原因,我需要使用红黑树结构,本以为拿来那份代码稍加改动就可以了,没想到代码调试了很久都还有问题,于是,我决定重新补习红黑树的知识,仔细查看了原有的代码,才发现是有问题的,在这里,给出修正版本的代码,希望这次是没有错误:) 请大家原谅我的疏忽。
我就不在原来的页面修改那份代码了,只是在上面加上说明那份代码是有错误的。
http://www.cppblog.com/converse/archive/2008/11/10/66530.html
在之前,我曾经给出过一份红黑树的实现代码,很多人提出异议,说是代码有问题,我曾经做过一些测试,貌似都没有出错,因为这份代码是在我学习红黑树之后很久才贴出来的,所以后来没有再仔细看这份代码。
最近,因为工作上的原因,我需要使用红黑树结构,本以为拿来那份代码稍加改动就可以了,没想到代码调试了很久都还有问题,于是,我决定重新补习红黑树的知识,仔细查看了原有的代码,才发现是有问题的,在这里,给出修正版本的代码,希望这次是没有错误:) 请大家原谅我的疏忽。
我就不在原来的页面修改那份代码了,只是在上面加上说明那份代码是有错误的。
/*-----------------------------------------------------------
RB - Tree的插入和删除操作的实现算法
参考资料:
1 ) << Introduction to algorithm >>
2 ) << STL源码剖析 >>
3 ) sgi - stl中stl_tree.h中的实现算法
4 ) http: // epaperpress.com / sortsearch / index.html
5 ) http: // www.ececs.uc.edu / ~franco / C321 / html / RedBlack / redblack.html
作者:李创 (http: // www.cppblog.com / converse / )
您可以自由的传播,修改这份代码,转载处请注明原作者
红黑树的几个性质:
1 ) 每个结点只有红和黑两种颜色
2 ) 根结点是黑色的
3 )空节点是黑色的(红黑树中,根节点的parent以及所有叶节点lchild、rchild都不指向NULL,而是指向一个定义好的空节点)。
4 ) 如果一个结点是红色的,那么它的左右两个子结点的颜色是黑色的
5 ) 对于每个结点而言,从这个结点到叶子结点的任何路径上的黑色结点
的数目相同
-------------------------------------------------------------*/
#include < stdio.h >
#include < stdlib.h >
#include < time .h >
typedef int KEY;
enum NODECOLOR
{
BLACK = 0 ,
RED = 1
};
typedef struct RBTree
{
struct RBTree * parent;
struct RBTree * left , * right ;
KEY key;
NODECOLOR color;
}RBTree, * PRBTree;
PRBTree RB_InsertNode(PRBTree root, KEY key);
PRBTree RB_InsertNode_Fixup(PRBTree root, PRBTree z);
PRBTree RB_DeleteNode(PRBTree root, KEY key);
PRBTree RB_DeleteNode_Fixup(PRBTree root, PRBTree x , PRBTree x_parent);
PRBTree Find_Node(PRBTree root, KEY key);
void Left_Rotate(PRBTree A, PRBTree & root);
void Right_Rotate(PRBTree A, PRBTree & root);
void Mid_Visit(PRBTree T);
void Mid_DeleteTree(PRBTree T);
void Print_Node(PRBTree node);
/*-----------------------------------------------------------
| A B
| / \ ==> / \
| a B A y
| / \ / \
| b y a b
-----------------------------------------------------------*/
void Left_Rotate(PRBTree A, PRBTree & root)
{
PRBTree B;
B = A -> right ;
A -> right = B -> left ;
if ( NULL ! = B -> left )
B -> left -> parent = A;
B -> parent = A -> parent;
// 这样三个判断连在一起避免了A -> parent = NULL的情况
if (A == root)
{
root = B;
}
else if (A == A -> parent -> left )
{
A -> parent -> left = B;
}
else
{
A -> parent -> right = B;
}
B -> left = A;
A -> parent = B;
}
/*-----------------------------------------------------------
| A B
| / \ / \
| B y ==> a A
| / \ / \
|a b b y
-----------------------------------------------------------*/
void Right_Rotate(PRBTree A, PRBTree & root)
{
PRBTree B;
B = A -> left ;
A -> left = B -> right ;
if ( NULL ! = B -> right )
B -> right -> parent = A;
B -> parent = A -> parent;
// 这样三个判断连在一起避免了A -> parent = NULL的情况
if (A == root)
{
root = B;
}
else if (A == A -> parent -> left )
{
A -> parent -> left = B;
}
else
{
A -> parent -> right = B;
}
A -> parent = B;
B -> right = A;
}
/*-----------------------------------------------------------
| 函数作用:查找key值对应的结点指针
| 输入参数:根节点root,待查找关键值key
| 返回参数:如果找到返回结点指针,否则返回NULL
-------------------------------------------------------------*/
PRBTree Find_Node(PRBTree root, KEY key)
{
PRBTree x;
// 找到key所在的node
x = root;
do
{
if (key == x -> key)
break;
if (key < x -> key)
{
if ( NULL ! = x -> left )
x = x -> left ;
else
break;
}
else
{
if ( NULL ! = x -> right )
x = x -> right ;
else
break;
}
} while ( NULL ! = x);
return x;
}
/*-----------------------------------------------------------
| 函数作用:在树中插入key值
| 输入参数:根节点root,待插入结点的关键值key
| 返回参数:根节点root
-------------------------------------------------------------*/
PRBTree RB_InsertNode(PRBTree root, KEY key)
{
PRBTree x, y;
PRBTree z;
if ( NULL == (z = (PRBTree)malloc(sizeof(RBTree))))
{
printf( " Memory alloc error\n " );
return NULL ;
}
z -> key = key;
// 得到z的父节点, 如果KEY已经存在就直接返回
x = root, y = NULL ;
while ( NULL ! = x)
{
y = x;
if (key < x -> key)
{
if ( NULL ! = x -> left )
{
x = x -> left ;
}
else
{
break;
}
}
else if (key > x -> key)
{
if ( NULL ! = x -> right )
{
x = x -> right ;
}
else
{
break;
}
}
else
{
return root;
}
}
if ( NULL == y || y -> key > key)
{
if ( NULL == y)
root = z;
else
y -> left = z;
}
else
{
y -> right = z;
}
// 设置z的左右子树为空并且颜色是red,注意新插入的节点颜色都是red
z -> parent = y;
z -> left = z -> right = NULL ;
z -> color = RED;
// 对红黑树进行修正
return RB_InsertNode_Fixup(root, z);
}
/*-----------------------------------------------------------
| 函数作用:对插入key值之后的树进行修正
| 输入参数:根节点root,插入的结点z
| 返回参数:根节点root
-------------------------------------------------------------*/
PRBTree RB_InsertNode_Fixup(PRBTree root, PRBTree z)
{
PRBTree y;
while (root ! = z && RED == z -> parent -> color) // 当z不是根同时父节点的颜色是red
{
if (z -> parent == z -> parent -> parent -> left ) // 父节点是祖父节点的左子树
{
y = z -> parent -> parent -> right ; // y为z的伯父节点
if ( NULL ! = y && RED == y -> color) // 伯父节点存在且颜色是red
{
z -> parent -> color = BLACK; // 更改z的父节点颜色是B
y -> color = BLACK; // 更改z的伯父节点颜色是B
z -> parent -> parent -> color = RED; // 更改z的祖父节点颜色是B
z = z -> parent -> parent; // 更新z为它的祖父节点
}
else // 无伯父节点或者伯父节点颜色是b
{
if (z == z -> parent -> right ) // 如果新节点是父节点的右子树
{
z = z -> parent;
Left_Rotate(z, root);
}
z -> parent -> color = BLACK; // 改变父节点颜色是B
z -> parent -> parent -> color = RED; // 改变祖父节点颜色是R
Right_Rotate(z -> parent -> parent, root);
}
}
else // 父节点为祖父节点的右子树
{
y = z -> parent -> parent -> left ; // y为z的伯父节点
if ( NULL ! = y && RED == y -> color) // 如果y的颜色是red
{
z -> parent -> color = BLACK; // 更改父节点的颜色为B
y -> color = BLACK; // 更改伯父节点的颜色是B
z -> parent -> parent -> color = RED; // 更改祖父节点颜色是R
z = z -> parent -> parent; // 更改z指向祖父节点
}
else // y不存在或者颜色是B
{
if (z == z -> parent -> left ) // 如果是父节点的左子树
{
z = z -> parent;
Right_Rotate(z, root);
}
z -> parent -> color = BLACK; // 改变父节点的颜色是B
z -> parent -> parent -> color = RED; // 改变祖父节点的颜色是RED
Left_Rotate(z -> parent -> parent, root);
}
}
} // while (RED == z -> parent -> color)
// 根节点的颜色始终都是B
root -> color = BLACK;
return root;
}
/*-----------------------------------------------------------
| 函数作用:在树中删除key值
| 输入参数:根节点root,待插入结点的关键值key
| 返回参数:根节点root
-------------------------------------------------------------*/
PRBTree RB_DeleteNode(PRBTree root, KEY key)
{
PRBTree x, y, z, x_parent;
// 首先查找需要删除的节点
z = Find_Node(root, key);
if ( NULL == z)
return root;
y = z, x = NULL , x_parent = NULL ;
// y是x按照中序遍历树的后继
if ( NULL == y -> left )
{
x = y -> right ;
}
else
{
if ( NULL == y -> right )
{
x = y -> left ;
}
else
{
y = y -> right ;
while ( NULL ! = y -> left )
y = y -> left ;
x = y -> right ;
}
}
if (y ! = z)
{
z -> left -> parent = y;
y -> left = z -> left ;
if (y ! = z -> right )
{
x_parent = y -> parent;
if ( NULL ! = x)
x -> parent = y -> parent;
y -> parent -> left = x;
y -> right = z -> right ;
z -> right -> parent = y;
}
else
{
x_parent = y;
}
if (root == z)
{
root = y;
}
else if (z == z -> parent -> left )
{
z -> parent -> left = y;
}
else
{
z -> parent -> right = y;
}
y -> parent = z -> parent;
NODECOLOR color = y -> color;
y -> color = z -> color;
z -> color = color;
y = z;
}
else
{
x_parent = y -> parent;
if ( NULL ! = x)
x -> parent = y -> parent;
if (root == z)
{
root = y;
}
else if (z == z -> parent -> left )
{
z -> parent -> left = x;
}
else
{
z -> parent -> right = x;
}
}
if (BLACK == y -> color)
{
root = RB_DeleteNode_Fixup(root, x, x_parent);
}
free(y);
return root;
}
/*-----------------------------------------------------------
| 函数作用:对删除key值之后的树进行修正
| 输入参数:根节点root,删除的结点的子结点x
| 返回参数:根节点root
-------------------------------------------------------------*/
PRBTree RB_DeleteNode_Fixup(PRBTree root, PRBTree x, PRBTree x_parent)
{
PRBTree w;
while (x ! = root && (NULL == x || BLACK == x -> color))
{
if (x == x_parent -> left ) // 如果x是左子树
{
w = x_parent -> right ; // w是x的兄弟结点
if (RED == w -> color) // 如果w的颜色是红色
{
w -> color = BLACK;
x_parent -> color = RED;
Left_Rotate(x_parent, root);
w = x_parent -> right ;
}
if (( NULL == w -> left || BLACK == w -> left -> color) &&
( NULL == w -> right || BLACK == w -> right -> color))
{
w -> color = RED;
x = x_parent;
x_parent = x_parent -> parent;
}
else
{
if ( NULL == w -> right || BLACK == w -> right -> color)
{
if ( NULL ! = w -> left )
w -> left -> color = BLACK;
w -> color = RED;
Right_Rotate(w, root);
w = x_parent -> right ;
}
w -> color = x_parent -> color;
x_parent -> color = BLACK;
if ( NULL ! = w -> right )
w -> right -> color = BLACK;
Left_Rotate(x -> parent, root);
break;
}
}
else
{
w = x_parent -> left ; // w是x的兄弟结点
if (RED == w -> color) // 如果w的颜色是红色
{
w -> color = BLACK;
x_parent -> color = RED;
Right_Rotate(x_parent, root);
w = x_parent -> left ;
}
if (( NULL == w -> left || BLACK == w -> left -> color) &&
( NULL == w -> right || BLACK == w -> right -> color))
{
w -> color = RED;
x = x_parent;
x_parent = x_parent -> parent;
}
else
{
if ( NULL == w -> left || BLACK == w -> left -> color)
{
if ( NULL ! = w -> right )
w -> right -> color = BLACK;
w -> color = RED;
Left_Rotate(w, root);
w = x_parent -> left ;
}
w -> color = x_parent -> color;
x_parent -> color = BLACK;
if ( NULL ! = w -> left )
w -> left -> color = BLACK;
Right_Rotate(x -> parent, root);
break;
}
}
}
x -> color = BLACK;
return root;
}
void Print_Node(PRBTree node)
{
char * color[] = { " BLACK " , " RED " };
printf( " Key = %d,\tcolor = %s " , node -> key, color[node -> color]);
if ( NULL ! = node -> parent)
printf( " ,\tparent = %d " , node -> parent -> key);
if ( NULL ! = node -> left )
printf( " ,\tleft = %d " , node -> left -> key);
if ( NULL ! = node -> right )
printf( " ,\tright = %d " , node -> right -> key);
printf( " \n " );
}
// 中序遍历树, 加了一个判断, 如果输出的数据不满足序列关系就报错退出
void Mid_Visit(PRBTree T)
{
if ( NULL ! = T)
{
if ( NULL ! = T -> left )
{
if (T -> left -> key > T -> key)
{
printf( " wrong!\n " );
exit ( - 1 );
}
Mid_Visit(T -> left );
}
Print_Node(T);
if ( NULL ! = T -> right )
{
if (T -> right -> key < T -> key)
{
printf( " wrong\n " );
exit ( - 1 );
}
Mid_Visit(T -> right );
}
}
}
// 中序删除树的各个节点
void Mid_DeleteTree(PRBTree T)
{
if ( NULL ! = T)
{
if ( NULL ! = T -> left )
Mid_DeleteTree(T -> left );
PRBTree temp = T -> right ;
free(T);
T = NULL ;
if ( NULL ! = temp)
Mid_DeleteTree(temp);
}
}
void Create_New_Array( int array [], int length)
{
for ( int i = 0 ; i < length; i ++ )
{
array [i] = rand() % 256 ;
}
}
int main( int argc, char * argv[])
{
srand( time ( NULL ));
PRBTree root = NULL ;
int i;
for (i = 0 ; i < 100000 ; i ++ )
{
root = RB_InsertNode(root, rand() % 10000 );
}
Mid_Visit(root);
// 删除整颗树
Mid_DeleteTree(root);
return 0 ;
}
RB - Tree的插入和删除操作的实现算法
参考资料:
1 ) << Introduction to algorithm >>
2 ) << STL源码剖析 >>
3 ) sgi - stl中stl_tree.h中的实现算法
4 ) http: // epaperpress.com / sortsearch / index.html
5 ) http: // www.ececs.uc.edu / ~franco / C321 / html / RedBlack / redblack.html
作者:李创 (http: // www.cppblog.com / converse / )
您可以自由的传播,修改这份代码,转载处请注明原作者
红黑树的几个性质:
1 ) 每个结点只有红和黑两种颜色
2 ) 根结点是黑色的
3 )空节点是黑色的(红黑树中,根节点的parent以及所有叶节点lchild、rchild都不指向NULL,而是指向一个定义好的空节点)。
4 ) 如果一个结点是红色的,那么它的左右两个子结点的颜色是黑色的
5 ) 对于每个结点而言,从这个结点到叶子结点的任何路径上的黑色结点
的数目相同
-------------------------------------------------------------*/
#include < stdio.h >
#include < stdlib.h >
#include < time .h >
typedef int KEY;
enum NODECOLOR
{
BLACK = 0 ,
RED = 1
};
typedef struct RBTree
{
struct RBTree * parent;
struct RBTree * left , * right ;
KEY key;
NODECOLOR color;
}RBTree, * PRBTree;
PRBTree RB_InsertNode(PRBTree root, KEY key);
PRBTree RB_InsertNode_Fixup(PRBTree root, PRBTree z);
PRBTree RB_DeleteNode(PRBTree root, KEY key);
PRBTree RB_DeleteNode_Fixup(PRBTree root, PRBTree x , PRBTree x_parent);
PRBTree Find_Node(PRBTree root, KEY key);
void Left_Rotate(PRBTree A, PRBTree & root);
void Right_Rotate(PRBTree A, PRBTree & root);
void Mid_Visit(PRBTree T);
void Mid_DeleteTree(PRBTree T);
void Print_Node(PRBTree node);
/*-----------------------------------------------------------
| A B
| / \ ==> / \
| a B A y
| / \ / \
| b y a b
-----------------------------------------------------------*/
void Left_Rotate(PRBTree A, PRBTree & root)
{
PRBTree B;
B = A -> right ;
A -> right = B -> left ;
if ( NULL ! = B -> left )
B -> left -> parent = A;
B -> parent = A -> parent;
// 这样三个判断连在一起避免了A -> parent = NULL的情况
if (A == root)
{
root = B;
}
else if (A == A -> parent -> left )
{
A -> parent -> left = B;
}
else
{
A -> parent -> right = B;
}
B -> left = A;
A -> parent = B;
}
/*-----------------------------------------------------------
| A B
| / \ / \
| B y ==> a A
| / \ / \
|a b b y
-----------------------------------------------------------*/
void Right_Rotate(PRBTree A, PRBTree & root)
{
PRBTree B;
B = A -> left ;
A -> left = B -> right ;
if ( NULL ! = B -> right )
B -> right -> parent = A;
B -> parent = A -> parent;
// 这样三个判断连在一起避免了A -> parent = NULL的情况
if (A == root)
{
root = B;
}
else if (A == A -> parent -> left )
{
A -> parent -> left = B;
}
else
{
A -> parent -> right = B;
}
A -> parent = B;
B -> right = A;
}
/*-----------------------------------------------------------
| 函数作用:查找key值对应的结点指针
| 输入参数:根节点root,待查找关键值key
| 返回参数:如果找到返回结点指针,否则返回NULL
-------------------------------------------------------------*/
PRBTree Find_Node(PRBTree root, KEY key)
{
PRBTree x;
// 找到key所在的node
x = root;
do
{
if (key == x -> key)
break;
if (key < x -> key)
{
if ( NULL ! = x -> left )
x = x -> left ;
else
break;
}
else
{
if ( NULL ! = x -> right )
x = x -> right ;
else
break;
}
} while ( NULL ! = x);
return x;
}
/*-----------------------------------------------------------
| 函数作用:在树中插入key值
| 输入参数:根节点root,待插入结点的关键值key
| 返回参数:根节点root
-------------------------------------------------------------*/
PRBTree RB_InsertNode(PRBTree root, KEY key)
{
PRBTree x, y;
PRBTree z;
if ( NULL == (z = (PRBTree)malloc(sizeof(RBTree))))
{
printf( " Memory alloc error\n " );
return NULL ;
}
z -> key = key;
// 得到z的父节点, 如果KEY已经存在就直接返回
x = root, y = NULL ;
while ( NULL ! = x)
{
y = x;
if (key < x -> key)
{
if ( NULL ! = x -> left )
{
x = x -> left ;
}
else
{
break;
}
}
else if (key > x -> key)
{
if ( NULL ! = x -> right )
{
x = x -> right ;
}
else
{
break;
}
}
else
{
return root;
}
}
if ( NULL == y || y -> key > key)
{
if ( NULL == y)
root = z;
else
y -> left = z;
}
else
{
y -> right = z;
}
// 设置z的左右子树为空并且颜色是red,注意新插入的节点颜色都是red
z -> parent = y;
z -> left = z -> right = NULL ;
z -> color = RED;
// 对红黑树进行修正
return RB_InsertNode_Fixup(root, z);
}
/*-----------------------------------------------------------
| 函数作用:对插入key值之后的树进行修正
| 输入参数:根节点root,插入的结点z
| 返回参数:根节点root
-------------------------------------------------------------*/
PRBTree RB_InsertNode_Fixup(PRBTree root, PRBTree z)
{
PRBTree y;
while (root ! = z && RED == z -> parent -> color) // 当z不是根同时父节点的颜色是red
{
if (z -> parent == z -> parent -> parent -> left ) // 父节点是祖父节点的左子树
{
y = z -> parent -> parent -> right ; // y为z的伯父节点
if ( NULL ! = y && RED == y -> color) // 伯父节点存在且颜色是red
{
z -> parent -> color = BLACK; // 更改z的父节点颜色是B
y -> color = BLACK; // 更改z的伯父节点颜色是B
z -> parent -> parent -> color = RED; // 更改z的祖父节点颜色是B
z = z -> parent -> parent; // 更新z为它的祖父节点
}
else // 无伯父节点或者伯父节点颜色是b
{
if (z == z -> parent -> right ) // 如果新节点是父节点的右子树
{
z = z -> parent;
Left_Rotate(z, root);
}
z -> parent -> color = BLACK; // 改变父节点颜色是B
z -> parent -> parent -> color = RED; // 改变祖父节点颜色是R
Right_Rotate(z -> parent -> parent, root);
}
}
else // 父节点为祖父节点的右子树
{
y = z -> parent -> parent -> left ; // y为z的伯父节点
if ( NULL ! = y && RED == y -> color) // 如果y的颜色是red
{
z -> parent -> color = BLACK; // 更改父节点的颜色为B
y -> color = BLACK; // 更改伯父节点的颜色是B
z -> parent -> parent -> color = RED; // 更改祖父节点颜色是R
z = z -> parent -> parent; // 更改z指向祖父节点
}
else // y不存在或者颜色是B
{
if (z == z -> parent -> left ) // 如果是父节点的左子树
{
z = z -> parent;
Right_Rotate(z, root);
}
z -> parent -> color = BLACK; // 改变父节点的颜色是B
z -> parent -> parent -> color = RED; // 改变祖父节点的颜色是RED
Left_Rotate(z -> parent -> parent, root);
}
}
} // while (RED == z -> parent -> color)
// 根节点的颜色始终都是B
root -> color = BLACK;
return root;
}
/*-----------------------------------------------------------
| 函数作用:在树中删除key值
| 输入参数:根节点root,待插入结点的关键值key
| 返回参数:根节点root
-------------------------------------------------------------*/
PRBTree RB_DeleteNode(PRBTree root, KEY key)
{
PRBTree x, y, z, x_parent;
// 首先查找需要删除的节点
z = Find_Node(root, key);
if ( NULL == z)
return root;
y = z, x = NULL , x_parent = NULL ;
// y是x按照中序遍历树的后继
if ( NULL == y -> left )
{
x = y -> right ;
}
else
{
if ( NULL == y -> right )
{
x = y -> left ;
}
else
{
y = y -> right ;
while ( NULL ! = y -> left )
y = y -> left ;
x = y -> right ;
}
}
if (y ! = z)
{
z -> left -> parent = y;
y -> left = z -> left ;
if (y ! = z -> right )
{
x_parent = y -> parent;
if ( NULL ! = x)
x -> parent = y -> parent;
y -> parent -> left = x;
y -> right = z -> right ;
z -> right -> parent = y;
}
else
{
x_parent = y;
}
if (root == z)
{
root = y;
}
else if (z == z -> parent -> left )
{
z -> parent -> left = y;
}
else
{
z -> parent -> right = y;
}
y -> parent = z -> parent;
NODECOLOR color = y -> color;
y -> color = z -> color;
z -> color = color;
y = z;
}
else
{
x_parent = y -> parent;
if ( NULL ! = x)
x -> parent = y -> parent;
if (root == z)
{
root = y;
}
else if (z == z -> parent -> left )
{
z -> parent -> left = x;
}
else
{
z -> parent -> right = x;
}
}
if (BLACK == y -> color)
{
root = RB_DeleteNode_Fixup(root, x, x_parent);
}
free(y);
return root;
}
/*-----------------------------------------------------------
| 函数作用:对删除key值之后的树进行修正
| 输入参数:根节点root,删除的结点的子结点x
| 返回参数:根节点root
-------------------------------------------------------------*/
PRBTree RB_DeleteNode_Fixup(PRBTree root, PRBTree x, PRBTree x_parent)
{
PRBTree w;
while (x ! = root && (NULL == x || BLACK == x -> color))
{
if (x == x_parent -> left ) // 如果x是左子树
{
w = x_parent -> right ; // w是x的兄弟结点
if (RED == w -> color) // 如果w的颜色是红色
{
w -> color = BLACK;
x_parent -> color = RED;
Left_Rotate(x_parent, root);
w = x_parent -> right ;
}
if (( NULL == w -> left || BLACK == w -> left -> color) &&
( NULL == w -> right || BLACK == w -> right -> color))
{
w -> color = RED;
x = x_parent;
x_parent = x_parent -> parent;
}
else
{
if ( NULL == w -> right || BLACK == w -> right -> color)
{
if ( NULL ! = w -> left )
w -> left -> color = BLACK;
w -> color = RED;
Right_Rotate(w, root);
w = x_parent -> right ;
}
w -> color = x_parent -> color;
x_parent -> color = BLACK;
if ( NULL ! = w -> right )
w -> right -> color = BLACK;
Left_Rotate(x -> parent, root);
break;
}
}
else
{
w = x_parent -> left ; // w是x的兄弟结点
if (RED == w -> color) // 如果w的颜色是红色
{
w -> color = BLACK;
x_parent -> color = RED;
Right_Rotate(x_parent, root);
w = x_parent -> left ;
}
if (( NULL == w -> left || BLACK == w -> left -> color) &&
( NULL == w -> right || BLACK == w -> right -> color))
{
w -> color = RED;
x = x_parent;
x_parent = x_parent -> parent;
}
else
{
if ( NULL == w -> left || BLACK == w -> left -> color)
{
if ( NULL ! = w -> right )
w -> right -> color = BLACK;
w -> color = RED;
Left_Rotate(w, root);
w = x_parent -> left ;
}
w -> color = x_parent -> color;
x_parent -> color = BLACK;
if ( NULL ! = w -> left )
w -> left -> color = BLACK;
Right_Rotate(x -> parent, root);
break;
}
}
}
x -> color = BLACK;
return root;
}
void Print_Node(PRBTree node)
{
char * color[] = { " BLACK " , " RED " };
printf( " Key = %d,\tcolor = %s " , node -> key, color[node -> color]);
if ( NULL ! = node -> parent)
printf( " ,\tparent = %d " , node -> parent -> key);
if ( NULL ! = node -> left )
printf( " ,\tleft = %d " , node -> left -> key);
if ( NULL ! = node -> right )
printf( " ,\tright = %d " , node -> right -> key);
printf( " \n " );
}
// 中序遍历树, 加了一个判断, 如果输出的数据不满足序列关系就报错退出
void Mid_Visit(PRBTree T)
{
if ( NULL ! = T)
{
if ( NULL ! = T -> left )
{
if (T -> left -> key > T -> key)
{
printf( " wrong!\n " );
exit ( - 1 );
}
Mid_Visit(T -> left );
}
Print_Node(T);
if ( NULL ! = T -> right )
{
if (T -> right -> key < T -> key)
{
printf( " wrong\n " );
exit ( - 1 );
}
Mid_Visit(T -> right );
}
}
}
// 中序删除树的各个节点
void Mid_DeleteTree(PRBTree T)
{
if ( NULL ! = T)
{
if ( NULL ! = T -> left )
Mid_DeleteTree(T -> left );
PRBTree temp = T -> right ;
free(T);
T = NULL ;
if ( NULL ! = temp)
Mid_DeleteTree(temp);
}
}
void Create_New_Array( int array [], int length)
{
for ( int i = 0 ; i < length; i ++ )
{
array [i] = rand() % 256 ;
}
}
int main( int argc, char * argv[])
{
srand( time ( NULL ));
PRBTree root = NULL ;
int i;
for (i = 0 ; i < 100000 ; i ++ )
{
root = RB_InsertNode(root, rand() % 10000 );
}
Mid_Visit(root);
// 删除整颗树
Mid_DeleteTree(root);
return 0 ;
}