#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct node
{
int data;
struct node *p;
struct node *left;
struct node *right;
char color;
}node,*linktree;
void Create_Tree();
void Insert(linktree T,int i);
void Insert_Fix(linktree s,linktree z);
void Left_Rotate(linktree s,linktree z);
void Right_Rotate(linktree s,linktree z);
void Inorder(linktree s);
void Delete(linktree z);
linktree Tree_Successor(linktree s);
void Delete_Fix(linktree s);
linktree Nil;
static linktree root;
int main()
{
Nil=(linktree)malloc(sizeof(node));//定义外节点,统一设置为Nil;
Nil->color='B';
Nil->p=NULL;
Nil->left=NULL;
Nil->right=NULL;
Nil->data=0;
Create_Tree();
return 0;
}
void Create_Tree()
{
linktree s;
int a[]={11,2,14,1,7,15,5,4,8};
int i;
root=(linktree)malloc(sizeof(node));//定义跟节点,着色为黑色
root->data=11;
root->p=Nil;
root->left=Nil;
root->right=Nil;
root->color='B';
printf("root=%p\n",root);
for(i=1;i<sizeof(a)/sizeof(int);i++)
{
printf("root=%p\n",root);
Insert(root,a[i]);
printf("root->data=%d\n",root->data);
}
Inorder(root);
Delete(root);
printf("\n\n");
Inorder(root);
}
void Insert(linktree T,int i)
{
linktree s,y;
s=T;
printf("%d ",i);
while(s!=Nil)//获取插入节点
{
y=s;//记下插入节点的父节点
if(s->data>i)
s=s->left;
else
s=s->right;
}
s=(linktree)malloc(sizeof(node));
if(y->data>i)//插入y的左节点
{
y->left=s;
s->p=y;
s->data=i;
s->right=Nil;
s->left=Nil;
s->color='R';
}
else//插入y的右节点
{
y->right=s;
s->p=y;
s->data=i;
s->right=Nil;
s->left=Nil;
s->color='R';
}
Insert_Fix(T,s);
}
void Left_Rotate( linktree s,linktree z)//为了保持红黑树的特性 对节点z 做左旋操作,节点z 的右孩子必须不是Nul
{
linktree y;
printf("左旋的值为:%d\n",z->data);
y=z->right;
z->right=y->left;
if(y->left!=Nil)
y->left->p=z;
y->p=z->p;
if(z->p==Nil) //判断z是z的父节点的左子树还是右子树
{
root=y; //把y赋值给跟节点
printf("改变左旋root?==%p,%d\n",root,root->data);
}
else{
if(z->p->left==z)
z->p->left=y;
else
z->p->right=y;
}
y->left=z; //把z放到y的左子树上
z->p=y;
}
void Right_Rotate(linktree s,linktree z)//为了保持红黑树的特性 对节点z 做右旋操作,节点z 的左孩子必须不是Nul
{
linktree y;
y=z->left;
z->left=y->right;
if(y->right!=Nil)
y->right->p=z;
y->p=z->p;
if(z->p==Nil)
{
root=y; //如果z是根节点,则把y变为跟节点
}
else
{
if(z->p->left==z)
z->p->left=y;
else
{
z->p->right=y;
}
}
y->right=z;
z->p=y;
}
void Insert_Fix(linktree s,linktree z) //修复插入过程中产生的不符合红黑树特性的情况
{
linktree y;
while(z->p->color=='R')
{
if(z->p==z->p->p->left) //如果Z的父节点是其祖父节点的左孩子
{
y=z->p->p->right; //把z的叔父赋值给y
if(y->color=='R') //z的叔父为红色,符合第一种情况,直接把z的父亲,z的叔父着色为黑色,
//把z的祖父着色为红色(为了保证红黑树的的第五条特性成立(每个节点到其子孙路径上的所有节点包含相同的黑节点))
{
z->p->color='B';
y->color='B';
z->p->p->color='R';
z=z->p->p; // z上溯..
}
else
{
if(z->p->right==z)//第二种情况 ,z是其父节点的右孩子,通过一次左旋把他转化成第三种情况
{
z=z->p;
Left_Rotate(s,z);
}
//第三种情况,z是其父节点的做孩子
z->p->color='B';
z->p->p->color='R';
Right_Rotate(s,z->p->p);
}
}
else //如果Z的父节点是其祖父节点的右孩子
{
y=z->p->p->left;
if(y->color=='R')
{
z->p->color='B';
y->color='B';
z->p->p->color='R';
z=z->p->p;
}
else
{
if(z->p->left==z)//右旋之..
{
z=z->p;
Right_Rotate(s,z);
}
z->p->color='B';
z->p->p->color='R';
Left_Rotate(s,z->p->p);
}
}
}
root->color='B';
}
void Inorder(linktree s) //树的遍历
{
if(s!=Nil)
{
Inorder(s->left);
printf("data=%d,color=%c,left=%d,right=%d,parent=%d\n",s->data,s->color,s->left->data,s->right->data,s->p->data);
Inorder(s->right);
}
}
void Delete(linktree z)
{
linktree x,y;
if(z->left==Nil || z->right==Nil) //找到需要删除的节点
y=z;
else
y=Tree_Successor(z);
if(y->left!=Nil)
x=y->left;
else
x=y->right;
x->p=y->p;
if(y->p==Nil)
root=y;
else if(y->p->left==y)
y->p->left=x;
else
y->p->right=x;
if (y!=z)
z->data=y->data;
if(y->color=='B')
Delete_Fix(x);
}
linktree Tree_Successor(linktree s) //查找节点的直接后继
{
linktree y;
if(s->right!=Nil)
{
y=s->right;
while(y->left!=Nil)
{
y=y->left;
}
}
else
{
y=s->p;
while(y!=Nil && s==y->right)
{
s=y;
y=y->p;
}
}
return y;
}
void Delete_Fix(linktree x) //删除节点后恢复红黑树的特性
{
linktree w;
while(x!=root&&x->color=='B')
{
if(x==x->p->left)
{
w=x->p->right;
if(w->color=='R')
{
w->color='B';
x->p->color='R';
Left_Rotate(root,x->p);
}
if(w->left->color=='B' && w->right->color=='B')
{
w->color='R';
x=x->p;
}
else
{
if(w->right->color=='B')
{
w->left->color='B';
w->color='R';
Right_Rotate(root,w);
w=x->p->right;
}
w->color=x->p->color;
x->p->color='B';
w->right->color='B';
Left_Rotate(root,x->p);
x=root;
}
}
else
{
w=x->p->left;
if(w->color=='R')
{
w->color='B';
x->p->color='R';
Right_Rotate(root,x->p);
}
if(w->left->color=='B' && w->right->color=='B')
{
w->color='R';
x=x->p;
}
else
{
if(w->left->color=='B')
{
w->right->color='B';
w->color='R';
Left_Rotate(root,w);
w=x->p->right;
}
w->color=x->p->color;
x->p->color='B';
w->left->color='B';
Right_Rotate(root,x->p);
x=root;
}
}
}
x->color='B';
}