算法导论 第十三章:红黑树
2015-07-16 17:24
375 查看
红黑树(red-black tree)是一种“平衡”查找树,它能保证最坏情况下,基本的动态集操作时间为O(lgn).
性质:
1)每个节点要么是红的,要么是黑的
2)根节点和叶子节点(NIL)是黑色的
3)若一个节点是红色的,则他的两个孩子节点是黑色的
4)对于每一个节点x,从该节点到其子酸节点的所有路径上包含相同数目的黑节点(#black nodes = black-height(x))
引理:
一棵有n个内节点的红黑树的高度至多为 2 lg(n+1)
红黑树上插入删除的完整代码如下:
#include<iostream>
#include<iomanip>
using namespace std;
#define BLACK 0
#define RED 1
typedef struct RBTNode{
int key;
bool color;
RBTNode *parent;
RBTNode *left;
RBTNode *right;
}RBTNode;
typedef struct RBTree{
RBTNode *root;
}RBTree;
RBTNode NILL={-1,BLACK,NULL,NULL,NULL};
RBTNode *NIL=&NILL; //init sentinel NIL
void RBT_InorderWalk(RBTNode *x)
{
if(x!=NIL)
{
RBT_InorderWalk(x->left);
cout<<setw(3)<<x->key;
if(x->color==1)
cout<<" Red"<<endl;
else
cout<<" Black"<<endl;
RBT_InorderWalk(x->right);
}
}
RBTNode *RBT_Search(RBTNode *x,int key)
{
if(x->key == key || x==NIL)
return x;
if(key < x->key)
RBT_Search(x->left,key);
else
RBT_Search(x->right,key);
}
RBTNode *RBT_Minimum(RBTNode *x)
{
while(x->left != NIL)
x=x->left;
return x;
}
void Left_Rotate(RBTree *T,RBTNode *x)
{
RBTNode *y=x->right; //set y
x->right=y->left; //turn y's left subtree into x's right subtree
if(y->left!=NIL)
y->left->parent=x;
y->parent=x->parent; //link x's parent to y;
if(x->parent == NIL)
T->root=y;
else if(x==x->parent->left)
x->parent->left=y;
else
x->parent->right=y;
y->left=x; //put x on y's left
x->parent=y;
}
void Right_Rotate(RBTree *T,RBTNode *x)
{
RBTNode *y=x->left; //set y
x->left=y->right; //link x's left tree into y's right subtree;
if(y->right !=NIL)
y->right->parent=x;
y->parent=x->parent; //link x's parent to y
if(x->parent == NIL)
T->root=y;
else if(x == x->parent->left)
x->parent->left=y;
else
x->parent->right=y;
y->right=x; //put x on y's right
x->parent=y;
}
void RBT_InsertFixup(RBTree *T,RBTNode *z)
{
while(z->parent->color==RED)
{
if(z->parent == z->parent->parent->left)
{
RBTNode *y=z->parent->parent->right;
if(y->color==RED)
{
z->parent->color=BLACK; //case 1
y->color=BLACK; //case 1
z->parent->parent->color=RED; //case 1
z=z->parent->parent; //case 1
}
else
{
if(z==z->parent->right)
{
z=z->parent; //case 2
Left_Rotate(T,z); //case 2
}
z->parent->color=BLACK; //case 3
z->parent->parent->color=RED; //case 3
Right_Rotate(T,z->parent->parent); //case 3
}
}
else
{//ame as then clause with "right" and "left" exchanged
RBTNode *y=z->parent->parent->left;
if(y->color==RED)
{
z->parent->color==BLACK;
y->color=BLACK;
z->parent->parent->color=RED;
z=z->parent->parent;
}
else
{
if(z==z->parent->left)
{
z=z->parent;
Right_Rotate(T,z);
}
z->parent->color=BLACK;
z->parent->parent->color=RED;
Left_Rotate(T,z->parent->parent);
}
}
}
T->root->color=BLACK; //turn the root to BLACK
}
void RBT_Insert(RBTree *T,int value)
{
RBTNode *z=new RBTNode();
z->key=value;
z->color =RED;
z->parent=NIL;
z->left=NIL;
z->right=NIL;
RBTNode *y=NIL; //y is the parent of x
RBTNode *x=T->root;
while(x != NIL)
{
y=x;
if(z->key < x->key)
x=x->left;
else
x=x->right;
}
z->parent=y; //link new node's parent node to y(y's child is NIL)
if(y==NIL)
T->root=z;
else if(z->key < y->key)
y->left=z;
else
y->right =z;
RBT_InsertFixup(T,z);
}
void RBT_Transplant(RBTree *T,RBTNode *u,RBTNode *v)
{
if(u->parent==NIL)
T->root=v;
else if(u==u->parent->left)
u->parent->left=v;
else
u->parent->right=v;
v->parent=u->parent;
}
void RBT_DeleteFixup(RBTree *T,RBTNode *x)
{
RBTNode *w;
while(x!=T->root && x->color==BLACK)
{
if(x==x->parent->left)
{
w=x->parent->right; //set w to x's sibling
if(w->color==RED) //case 1:x's sibling w is red
{
w->color=BLACK;
x->parent->color=RED;
Left_Rotate(T,x->parent);
w=x->parent->right;
}
if(w->left->color==BLACK && w->right->color==BLACK)
{ //case 2:x's sibling w is black and both of w's children are black
w->color=RED;
x=x->parent;
}
else
{
if(w->right->color==BLACK)
{//case 3:x's sibling w is black,w's left child is red, and w's right child is black
w->left->color=BLACK;
w->color=RED;
Right_Rotate(T,w);
w=x->parent->right;
}
w->color=x->parent->color; //case 4: x's sibling w is black,and w's right child is red
x->parent->color=BLACK; //.
w->right->color=BLACK; // .
Left_Rotate(T,x->parent); // .
x=T->root; //case 4
}
}
else
{//Same as then clause with "right" and "left" exchanged
w=x->parent->left;
if(w->color==RED)
{
w->color=BLACK;
x->parent->color=RED;
Right_Rotate(T,x->parent);
w=x->parent->left;
}
if(w->left->color==BLACK && w->right->color==BLACK)
{
w->color=RED;
x=x->parent;
}
else
{
if(w->left->color==BLACK)
{
w->right->color=BLACK;
w->color=RED;
Left_Rotate(T,w);
w=x->parent->left;
}
w->color=x->parent->color;
x->parent->color=BLACK;
w->left->color=BLACK;
Right_Rotate(T,x->parent);
x=T->root;
}
}
}
x->color=BLACK;
}
/*RBTNode *RBT_Successor(RBTNode *x){
RBTNode *r = x;
if(r->right != NIL)
return RBT_Minimum(r->right);
RBTNode *y = r->parent;
while(y != NIL && r == y->right){
r = y;
y = y->parent;
}
return y;
}*/
void RBT_Delete(RBTree *T,RBTNode *z)
{
RBTNode *x=NULL,*y=NULL;
bool y_origin_color;
y=z;
y_origin_color=y->color;
if(z->left == NIL)
{
x=z->right;
RBT_Transplant(T,z,z->right);
}
else if(z->right ==NIL)
{
x=z->left;
RBT_Transplant(T,z,z->left);
}
else
{
y=RBT_Minimum(z->right);
y_origin_color=y->color;
x=y->right;
if(y->parent==z)
x->parent=y;
else
{
RBT_Transplant(T,y,y->right);
y->right=z->right;
y->right->parent=y;
}
RBT_Transplant(T,z,y);
y->left=z->left;
y->left->parent=y;
y->color=z->color;
}
if(y_origin_color==BLACK)
RBT_DeleteFixup(T,x);
}
int main()
{
int A[]={41,38,31,12,19,8};
int n=sizeof(A)/sizeof(int);
cout<<"/*--------------------Ceate Red-Black tree------------------*/"<<endl;
RBTree *T=new RBTree();
T->root=NIL;
for(int i=0;i<n;i++)
RBT_Insert(T,A[i]);
cout<<"The Red-Black tree is:"<<endl;
RBT_InorderWalk(T->root);
cout<<"Th
ae49
e root of the RBT is:"<<T->root->key<<endl;
cout<<"/*----------------------------------------------------------*/"<<endl;
cout<<"/*----------------------RBT Insertion-----------------------*/"<<endl;
int ikey;
cout<<"Please input the inserting key:";
cin>>ikey;
RBT_Insert(T,ikey);
cout<<"After insertion,the RBT is:"<<endl;
RBT_InorderWalk(T->root);
cout<<"The root of the RBT is:"<<T->root->key<<endl;
cout<<"/*-----------------------------------------------------------*/"<<endl;
cout<<"/*---------------------RBT Deletion-------------------------*/"<<endl;
int dkey;
cout<<"Please input the deleting key:";
cin>>dkey;
RBTNode *dNode=NULL;
dNode=RBT_Search(T->root,dkey);
if(dNode==NULL)
cout<<"The deleting key doesn't exist."<<endl;
else
{
RBT_Delete(T,dNode);
cout<<"After deletion,the RBT is:"<<endl;
RBT_InorderWalk(T->root);
cout<<"The root of the RBT is:"<<T->root->key<<endl;
}
return 0;
}
运行结果如下:
性质:
1)每个节点要么是红的,要么是黑的
2)根节点和叶子节点(NIL)是黑色的
3)若一个节点是红色的,则他的两个孩子节点是黑色的
4)对于每一个节点x,从该节点到其子酸节点的所有路径上包含相同数目的黑节点(#black nodes = black-height(x))
引理:
一棵有n个内节点的红黑树的高度至多为 2 lg(n+1)
红黑树上插入删除的完整代码如下:
#include<iostream>
#include<iomanip>
using namespace std;
#define BLACK 0
#define RED 1
typedef struct RBTNode{
int key;
bool color;
RBTNode *parent;
RBTNode *left;
RBTNode *right;
}RBTNode;
typedef struct RBTree{
RBTNode *root;
}RBTree;
RBTNode NILL={-1,BLACK,NULL,NULL,NULL};
RBTNode *NIL=&NILL; //init sentinel NIL
void RBT_InorderWalk(RBTNode *x)
{
if(x!=NIL)
{
RBT_InorderWalk(x->left);
cout<<setw(3)<<x->key;
if(x->color==1)
cout<<" Red"<<endl;
else
cout<<" Black"<<endl;
RBT_InorderWalk(x->right);
}
}
RBTNode *RBT_Search(RBTNode *x,int key)
{
if(x->key == key || x==NIL)
return x;
if(key < x->key)
RBT_Search(x->left,key);
else
RBT_Search(x->right,key);
}
RBTNode *RBT_Minimum(RBTNode *x)
{
while(x->left != NIL)
x=x->left;
return x;
}
void Left_Rotate(RBTree *T,RBTNode *x)
{
RBTNode *y=x->right; //set y
x->right=y->left; //turn y's left subtree into x's right subtree
if(y->left!=NIL)
y->left->parent=x;
y->parent=x->parent; //link x's parent to y;
if(x->parent == NIL)
T->root=y;
else if(x==x->parent->left)
x->parent->left=y;
else
x->parent->right=y;
y->left=x; //put x on y's left
x->parent=y;
}
void Right_Rotate(RBTree *T,RBTNode *x)
{
RBTNode *y=x->left; //set y
x->left=y->right; //link x's left tree into y's right subtree;
if(y->right !=NIL)
y->right->parent=x;
y->parent=x->parent; //link x's parent to y
if(x->parent == NIL)
T->root=y;
else if(x == x->parent->left)
x->parent->left=y;
else
x->parent->right=y;
y->right=x; //put x on y's right
x->parent=y;
}
void RBT_InsertFixup(RBTree *T,RBTNode *z)
{
while(z->parent->color==RED)
{
if(z->parent == z->parent->parent->left)
{
RBTNode *y=z->parent->parent->right;
if(y->color==RED)
{
z->parent->color=BLACK; //case 1
y->color=BLACK; //case 1
z->parent->parent->color=RED; //case 1
z=z->parent->parent; //case 1
}
else
{
if(z==z->parent->right)
{
z=z->parent; //case 2
Left_Rotate(T,z); //case 2
}
z->parent->color=BLACK; //case 3
z->parent->parent->color=RED; //case 3
Right_Rotate(T,z->parent->parent); //case 3
}
}
else
{//ame as then clause with "right" and "left" exchanged
RBTNode *y=z->parent->parent->left;
if(y->color==RED)
{
z->parent->color==BLACK;
y->color=BLACK;
z->parent->parent->color=RED;
z=z->parent->parent;
}
else
{
if(z==z->parent->left)
{
z=z->parent;
Right_Rotate(T,z);
}
z->parent->color=BLACK;
z->parent->parent->color=RED;
Left_Rotate(T,z->parent->parent);
}
}
}
T->root->color=BLACK; //turn the root to BLACK
}
void RBT_Insert(RBTree *T,int value)
{
RBTNode *z=new RBTNode();
z->key=value;
z->color =RED;
z->parent=NIL;
z->left=NIL;
z->right=NIL;
RBTNode *y=NIL; //y is the parent of x
RBTNode *x=T->root;
while(x != NIL)
{
y=x;
if(z->key < x->key)
x=x->left;
else
x=x->right;
}
z->parent=y; //link new node's parent node to y(y's child is NIL)
if(y==NIL)
T->root=z;
else if(z->key < y->key)
y->left=z;
else
y->right =z;
RBT_InsertFixup(T,z);
}
void RBT_Transplant(RBTree *T,RBTNode *u,RBTNode *v)
{
if(u->parent==NIL)
T->root=v;
else if(u==u->parent->left)
u->parent->left=v;
else
u->parent->right=v;
v->parent=u->parent;
}
void RBT_DeleteFixup(RBTree *T,RBTNode *x)
{
RBTNode *w;
while(x!=T->root && x->color==BLACK)
{
if(x==x->parent->left)
{
w=x->parent->right; //set w to x's sibling
if(w->color==RED) //case 1:x's sibling w is red
{
w->color=BLACK;
x->parent->color=RED;
Left_Rotate(T,x->parent);
w=x->parent->right;
}
if(w->left->color==BLACK && w->right->color==BLACK)
{ //case 2:x's sibling w is black and both of w's children are black
w->color=RED;
x=x->parent;
}
else
{
if(w->right->color==BLACK)
{//case 3:x's sibling w is black,w's left child is red, and w's right child is black
w->left->color=BLACK;
w->color=RED;
Right_Rotate(T,w);
w=x->parent->right;
}
w->color=x->parent->color; //case 4: x's sibling w is black,and w's right child is red
x->parent->color=BLACK; //.
w->right->color=BLACK; // .
Left_Rotate(T,x->parent); // .
x=T->root; //case 4
}
}
else
{//Same as then clause with "right" and "left" exchanged
w=x->parent->left;
if(w->color==RED)
{
w->color=BLACK;
x->parent->color=RED;
Right_Rotate(T,x->parent);
w=x->parent->left;
}
if(w->left->color==BLACK && w->right->color==BLACK)
{
w->color=RED;
x=x->parent;
}
else
{
if(w->left->color==BLACK)
{
w->right->color=BLACK;
w->color=RED;
Left_Rotate(T,w);
w=x->parent->left;
}
w->color=x->parent->color;
x->parent->color=BLACK;
w->left->color=BLACK;
Right_Rotate(T,x->parent);
x=T->root;
}
}
}
x->color=BLACK;
}
/*RBTNode *RBT_Successor(RBTNode *x){
RBTNode *r = x;
if(r->right != NIL)
return RBT_Minimum(r->right);
RBTNode *y = r->parent;
while(y != NIL && r == y->right){
r = y;
y = y->parent;
}
return y;
}*/
void RBT_Delete(RBTree *T,RBTNode *z)
{
RBTNode *x=NULL,*y=NULL;
bool y_origin_color;
y=z;
y_origin_color=y->color;
if(z->left == NIL)
{
x=z->right;
RBT_Transplant(T,z,z->right);
}
else if(z->right ==NIL)
{
x=z->left;
RBT_Transplant(T,z,z->left);
}
else
{
y=RBT_Minimum(z->right);
y_origin_color=y->color;
x=y->right;
if(y->parent==z)
x->parent=y;
else
{
RBT_Transplant(T,y,y->right);
y->right=z->right;
y->right->parent=y;
}
RBT_Transplant(T,z,y);
y->left=z->left;
y->left->parent=y;
y->color=z->color;
}
if(y_origin_color==BLACK)
RBT_DeleteFixup(T,x);
}
int main()
{
int A[]={41,38,31,12,19,8};
int n=sizeof(A)/sizeof(int);
cout<<"/*--------------------Ceate Red-Black tree------------------*/"<<endl;
RBTree *T=new RBTree();
T->root=NIL;
for(int i=0;i<n;i++)
RBT_Insert(T,A[i]);
cout<<"The Red-Black tree is:"<<endl;
RBT_InorderWalk(T->root);
cout<<"Th
ae49
e root of the RBT is:"<<T->root->key<<endl;
cout<<"/*----------------------------------------------------------*/"<<endl;
cout<<"/*----------------------RBT Insertion-----------------------*/"<<endl;
int ikey;
cout<<"Please input the inserting key:";
cin>>ikey;
RBT_Insert(T,ikey);
cout<<"After insertion,the RBT is:"<<endl;
RBT_InorderWalk(T->root);
cout<<"The root of the RBT is:"<<T->root->key<<endl;
cout<<"/*-----------------------------------------------------------*/"<<endl;
cout<<"/*---------------------RBT Deletion-------------------------*/"<<endl;
int dkey;
cout<<"Please input the deleting key:";
cin>>dkey;
RBTNode *dNode=NULL;
dNode=RBT_Search(T->root,dkey);
if(dNode==NULL)
cout<<"The deleting key doesn't exist."<<endl;
else
{
RBT_Delete(T,dNode);
cout<<"After deletion,the RBT is:"<<endl;
RBT_InorderWalk(T->root);
cout<<"The root of the RBT is:"<<T->root->key<<endl;
}
return 0;
}
运行结果如下:
相关文章推荐
- “百度与站长”更新:关于网站收录,删除,seo等
- 用vbs删除某些类型文件和磁盘空间报告的脚本
- QQ聊天记录删除了怎么恢复简单方法
- vbs删除注册表项的代码
- 迅速删除非法文件名的批处理代码
- 通过批处理实现删除运行、查找等处的历史记录的代码
- Shell中删除某些文件外所有文件的3个方法
- 删除文件提示文件正在被另一个人或程序使用的解决方法
- 关于.LDB文件 .ldb文件的产生 .ldb文件的删除方法
- asp 合并记录集并删除的sql语句
- SQLserver 数据库危险存储过程删除与恢复方法
- sql自增长设置与删除的深入分析
- 使用 Iisext.vbs 删除 Web 服务扩展文件的方法
- linux oracle数据库删除操作指南
- jQuery删除一个元素后淡出效果展示删除过程的方法
- 使用 Iisftpdr.vbs 删除FTP虚拟目录(支持本地与远程)
- 必须会的SQL语句(四) 数据删除和更新
- mssql SA帐号的改名和删除
- Oracle中插入特殊字符:&和'的解决方法汇总
- 将数据插入到MySQL表中的详细教程