首页 > 代码库 > 算法11---红黑树不带父结点指针的插入实现
算法11---红黑树不带父结点指针的插入实现
算法11---红黑树不带父结点指针的插入实现
1 #include <iostream> 2 using namespace std; 3 #define BLACK 0 4 #define RED 1 5 #define Nil -1 6 #define LEN sizeof(struct Tree) 7 struct Tree 8 { 9 struct Tree*left; 10 struct Tree*right; 11 int key; 12 int color; 13 }; 14 struct Tree*root=NULL; 15 struct Tree*nil=NULL; 16 //非递归版本的二叉查找树查找函数 17 struct Tree*ITERATIVE_TREE_SEARCH(struct Tree*x,int k,struct Tree*&p1,struct Tree*&p2) 18 {// 19 while (x!=nil&&k!=x->key) 20 { 21 p1=x; 22 if (k<x->key) 23 { 24 x=x->left; 25 } 26 else x=x->right; 27 if(k!=x->key)//如果没找到了待查找值,那么继续记录其祖父和父结点值。 28 { 29 p2=p1; 30 p1=x; 31 } 32 } 33 return x; 34 } 35 void LEFT_ROTATE(struct Tree*T,struct Tree*x) 36 {//左旋转:分三个步骤①②③来叙述旋转代码的。 37 struct Tree*p1=nil,*p2=nil; 38 struct Tree*y=x->right;//设置y结点。 39 x->right=y->left;//本行代码以及下面的if结构表达的是“y的左孩子成为x的右孩子”。① 40 ITERATIVE_TREE_SEARCH(root,x->key,p1,p2); 41 if(p1==nil)//本行代码以及下面的if-else结构表达的过程是“y成为该子树新的根”。② 42 { 43 root=y; 44 } 45 else if(x==p1->left) 46 { 47 p1->left=y; 48 } 49 else p1->right=y; 50 y->left=x;//本行代码以及下面一行都表达了“x成为y的左孩子”。③ 51 } 52 void RIGHT_ROTATE(struct Tree*T,struct Tree*x) 53 {//右旋转 54 struct Tree*p1=nil,*p2=nil; 55 struct Tree*y=x->left; 56 x->left=y->right; 57 ITERATIVE_TREE_SEARCH(root,x->key,p1,p2); 58 if(p1==nil) 59 { 60 root=y; 61 } 62 else if(x==p1->right) 63 { 64 p1->right=y; 65 } 66 else p1->left=y; 67 y->right=x; 68 } 69 void RB_INSERT_INSERT_FIXUP(struct Tree*T,struct Tree*z) 70 { 71 struct Tree*p1=nil,*p2=nil; 72 ITERATIVE_TREE_SEARCH(root,z->key,p1,p2);//p1=z->parent,p2=z->parent->parent 73 while (1) 74 { 75 ITERATIVE_TREE_SEARCH(root,z->key,p1,p2);//p1是父结点 p2是祖父结点 76 if (p1->color!=RED) 77 { 78 break; 79 } 80 if (p1==p2->left) 81 { 82 struct Tree*y=p2->right;//叔结点 83 if (y->color==RED)//情况一:叔结点为红色 84 {//给p1,y,p2着色以保持性质5。并且解决了z的父结点和z都是红色结点问题 85 p1->color=BLACK; 86 y->color=BLACK; 87 p2->color=RED; 88 z=p2;//把z的祖父结点当成新结点z进入下一次循环 89 } 90 else 91 { 92 if (z==p1->right)//情况二:检查z是否是一个右孩子且叔结点为黑色,前提是p1结点不是叶子结点 93 {//使用一个左旋让情况2转变为情况3 94 z=p1; 95 LEFT_ROTATE(T,z);//由于进入if语句后可知旋转结点不可能是叶子结点,这样就不用判断z是否是叶子结点了。 96 ITERATIVE_TREE_SEARCH(root,z->key,p1,p2);//p1=z->parent,p2=z->parent->parent 97 } 98 p1->color=BLACK;//情况三:是z是一个左孩子且叔结点为黑色,改变z的父和祖父结点颜色并做一次右旋,以保持性质5。 99 p2->color=RED;100 if(p2!=nil) RIGHT_ROTATE(T,p2);//由于p2可能是叶子结点,所以最好还是用一个if判断101 }102 }103 else//下面else分支类似于上面104 {105 struct Tree*y=p2->left;106 if (y->color==RED)107 {108 p1->color=BLACK;109 y->color=BLACK;110 p2->color=RED;111 z=p2;112 }113 else114 {115 if (z==p1->left)116 {117 z=p1;118 RIGHT_ROTATE(T,z);119 ITERATIVE_TREE_SEARCH(root,z->key,p1,p2);120 }121 p1->color=BLACK;122 p2->color=RED;123 if(p2!=nil) LEFT_ROTATE(T,p2);124 }125 }126 }127 root->color=BLACK;//最后给根结点着为黑色。128 }129 void RB_INSERT(struct Tree*T,struct Tree*z)130 {131 struct Tree*y=nil;132 struct Tree*x=root;133 while (x!=nil)134 {135 y=x;136 if (z->key<x->key)137 {138 x=x->left;139 }140 else x=x->right;141 }142 if (y==nil)143 {144 root=z;145 }146 else if(z->key<y->key)147 {148 y->left=z;149 }150 else y->right=z;151 z->left=nil;152 z->right=nil;153 z->color=RED;154 RB_INSERT_INSERT_FIXUP(T,z);155 }156 //中序遍历157 void InOderTraverse(struct Tree *p)158 {159 if (p!=nil)160 { 161 InOderTraverse(p->left);162 cout<<p->key<<" "<<p->color<<" "<<endl;163 InOderTraverse(p->right);164 }165 }166 void main()167 {168 nil=new struct Tree[LEN];169 nil->key=Nil;nil->color=BLACK;170 root=nil;171 int i=0;172 struct Tree*ROOT=new struct Tree[LEN];173 cin>>ROOT->key;174 RB_INSERT(nil,ROOT);175 root=ROOT;176 while (i!=12)177 {178 struct Tree*z=new struct Tree[LEN];179 cin>>z->key;180 RB_INSERT(root,z);181 i++;182 }183 InOderTraverse(root);184 }
算法11---红黑树不带父结点指针的插入实现
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。