1.简介:红黑树实现代码,主要功能有节点的插入,节点的删除等等。主函数主要来测试插入与删除的功能。(linux环境)
2.基础知识准备:红黑树原理,C语言基础。
3.注意事项:
1)对象红黑树的原理要有很好的理解(算法导论),以及C语言中的数值
传递。(如果你感觉越写越乱,你就回头看看原理吧,其中肯定有你没弄
清楚的)
2)建议用创建一个固定的空间来替代NULL,可以减少空指针的引用。
3)如果没有函数声明而直接定义,函数定义的顺序需要你注意下。
4.个人的收获,缺点与加强:
收获:更进一步的理解了红黑树,c语言的知识。
缺点:
1)在更复杂的程序下,我的版本控制肯定会混乱。
2)在自认为已经很好的理解的红黑树与C语言基础的情况
下,写足足写了一个星期完成红黑树的实现与简单的测试。
3)测试程序较简单。
5.以下是代码:
#include<stdio.h> #include<stdlib.h> #include<stdbool.h> #include<string.h> struct NODE{//树的节点的结构 int data; bool color;//1表示黑色,0表示红色 struct NODE*left; struct NODE*right; struct NODE*p; }; struct HEAD{//树根的结构 struct NODE*root; struct NODE*nil; }; void LEFT_ROTATE(struct HEAD*T,struct NODE*x)//左旋 { struct NODE*y=T->nil; y=x->right; x->right=y->left; if(y->left!=T->nil) y->left->p=x; y->p=x->p; if(x->p==T->nil) T->root=y; else if(x==x->p->left) x->p->left=y; else x->p->right=y; y->left=x; x->p=y; } void RIGHT_ROTATE(struct HEAD*T,struct NODE*y)//右旋 { struct NODE*x=T->nil; x=y->left; y->left=x->right; if(x->right!=T->nil) x->right->p=y; x->p=y->p; if(y->p==T->nil) T->root=x; else if(y==y->p->left) y->p->left=x; else y->p->right=x; x->right=y; y->p=x; } int JUDGE(struct HEAD*T,struct NODE*x)//测试一个节点的左子树与右子树的黑高是否相等 { int leftcount=0; int rightcount=0; struct NODE*leftwalk=T->nil; struct NODE*rightwalk=T->nil; if(x!=T->nil) { leftwalk=x->left; rightwalk=x->right; } while(leftwalk!=T->nil) { if(leftwalk->color==1) leftcount+=1; if(random()%2==0) leftwalk=leftwalk->left; else leftwalk=leftwalk->right; } while(rightwalk!=T->nil) { if(rightwalk->color==1) rightcount+=1; if(random()%2==0) rightwalk=rightwalk->left; else rightwalk=rightwalk->right; } if(leftcount==rightcount) return leftcount; else return -1; } void INORDER_WALK(struct HEAD*T,struct NODE*x)//前序遍历,打印出其数据与颜色 { if(x!=T->nil) { printf("data:%d color:%d\n",x->data,x->color); INORDER_WALK(T,x->left); INORDER_WALK(T,x->right); } } void INORDER_WALK_JUDGE (struct HEAD*T,struct NODE*x)//前序遍历,打印出黑高不相等的节点 { if(x!=T->nil) { // printf("high:%d\n",JUDGE(T,x)); if(JUDGE(T,x)==-1) printf("data:%d color:%d\n",x->data,x->color); INORDER_WALK_JUDGE(T,x->left); INORDER_WALK_JUDGE(T,x->right); } } void RB_INSERT_FIXUP(struct HEAD*T,struct NODE*z)//插入节点后的维护 { struct NODE*y=T->nil; if(z->p!=T->nil) while(z->p->color==0) { if(z->p->p==T->nil) break; else if(z->p==z->p->p->left) { y=z->p->p->right; if(y!=T->nil) { if(y->color==0) { z->p->color=1; y->color=1; z->p->p->color=0; z=z->p->p; continue; } } if(z==z->p->right) { z=z->p; LEFT_ROTATE(T,z); } z->p->color=1; z->p->p->color=0; RIGHT_ROTATE(T,z->p->p); } else { y=z->p->p->left; if(y!=T->nil) { if(y->color==0) { z->p->color=1; y->color=1; z->p->p->color=0; z=z->p->p; continue; } } if(z==z->p->left) { z=z->p; RIGHT_ROTATE(T,z); } z->p->color=1; z->p->p->color=0; LEFT_ROTATE(T,z->p->p); } } T->root->color=1; } void RB_INSERT(struct HEAD*T,struct NODE*z)//插入节点 { struct NODE*y=T->nil; struct NODE*x=T->root; while(x!=T->nil) { y=x; if(z->data<x->data) x=x->left; else x=x->right; } z->p=y; if(y==T->nil) T->root=z; else if(z->data<y->data) y->left=z; else y->right=z; z->left=T->nil; z->right=T->nil; z->color=0; RB_INSERT_FIXUP(T,z); } void RB_TRANSPLANT(struct HEAD*T,struct NODE*u,struct NODE*v)//v节点替代u节点 { if(u->p==T->nil) T->root=v; else if(u==u->p->left) u->p->left=v; else u->p->right=v; v->p=u->p; } void RB_DELETE_FIXUP(struct HEAD*T,struct NODE*x)//删除后的维护 { struct NODE*w=T->nil; bool signal; while(x!=T->root&&x->color==1) { signal=1; if(x==x->p->left) { w=x->p->right; if(w->color==0) { w->color=1; x->p->color=0; LEFT_ROTATE(T,x->p); w=x->p->right; signal=0; } else if(w->left->color==1&&w->right->color==1) { w->color=0; x=x->p; if(signal==0) break; else continue; } else if(w->right->color==1) { w->left->color=1; w->color=0; RIGHT_ROTATE(T,w); w=x->p->right; } w->color=x->p->color; x->p->color=1; w->right->color=1; LEFT_ROTATE(T,x->p); x=T->root; } else { w=x->p->left; if(w->color==0) { w->color=1; x->p->color=0; RIGHT_ROTATE(T,x->p); w=x->p->left; signal=0; } else if(w->left->color==1&&w->right->color==1) { w->color=0; x=x->p; if(signal==0) break; else continue; } else if(w->left->color==1) { w->right->color=1; w->color=0; LEFT_ROTATE(T,w); w=x->p->left; } w->color=x->p->color; x->p->color=1; w->left->color=1; RIGHT_ROTATE(T,x->p); x=T->root; } } x->color=1; } void RB_DELETE(struct HEAD*T,struct NODE*z)//删除节点 { struct NODE*y=z; struct NODE*x=T->nil; struct NODE*temp=T->nil; int y_original_color=y->color; if(z->left==T->nil) { x=z->right; RB_TRANSPLANT(T,z,z->right); } else if(z->right==T->nil) { x=z->left; RB_TRANSPLANT(T,z,z->left); } else { y=z->right; temp=y; while(y!=T->nil) { temp=y; y=y->left; } y=temp; y_original_color=y->color; x=y->right; if(y->p==z) { x->p=y; } else { RB_TRANSPLANT(T,y,y->right); y->right=z->right; y->right->p=y; } RB_TRANSPLANT(T,z,y); y->left=z->left; y->left->p=y; y->color=z->color; } if(y_original_color==1) RB_DELETE_FIXUP(T,x); } int main() { int test=1000000;//插入节点的数量 int value; struct NODE nilvalue={0,1,NULL,NULL,NULL};//替代NULL,所创建的空间 struct HEAD tree={&nilvalue,&nilvalue};//保存树根信息的空间,方便函数间传递 struct NODE*addnode=tree.nil; struct NODE*delwalk=tree.nil; struct NODE*bottom=tree.nil; int count=0; while(count<test)//插入节点 { addnode=(struct NODE*)malloc(sizeof(struct NODE)); value=random()%(test*100); addnode->data=value; RB_INSERT(&tree,addnode); count++; } INORDER_WALK_JUDGE(&tree,tree.root);//遍历并判断节点黑高是否相等 getchar(); delwalk=tree.root; while(delwalk!=tree.nil)//随机取得子树节点 { bottom=delwalk; if(random()%2==0) delwalk=delwalk->left; else delwalk=delwalk->right; } delwalk=bottom; while(delwalk!=tree.root)//根基获得的子树节点,删除沿这个子树上升的父节点 { RB_DELETE(&tree,delwalk);
free(delwalk); delwalk=delwalk->p; } INORDER_WALK_JUDGE(&tree,tree.root);//遍历并判断节点黑高是否相等 return 0; }
浙公网安备 33010602011771号