红黑树(C语言实现)

      因为看内核的时候感觉红黑树挺有意思的,所以利用周末的时间来实现一下玩玩。红黑树的操作主要是插入和删除,而删除的时候需要考虑的情况更多一些。具体的操作就不在这里罗嗦了,百度文库里面有一个比较有好的文章,已经说的很明白了。

      在看具体的操作的时候有的人可能感觉有些情况是没有考虑到的如果没有这种感觉的人很有可能根本没有仔细地想)。但是那些遗漏的情况如果存在的话操作之前的红黑树将违反那几个规则

      写代码的时候很多次因为少考虑情况而导致错误,细节比较多,刚开始rb_node中没有指向父节点的指针写的快吐血然后还是加上了代码具体的含义可以结合文章和注释来看还是很好理解的)。下面的代码中可能还有没有考虑到的细节,欢迎拍砖。

  1 #include <stdio.h>
2 #include <stdlib.h>
3
4 const int RED = 0;
5 const int BLACK = 1;
6
7 struct rb_node{
8 rb_node* lchild, *rchild, *parent;
9 int key, colour;
10 };
11 rb_node* root;
12
13 rb_node* get_node(rb_node* parent, int key);
14 void rb_insert(int key);
15 rb_node* rb_search(int key);
16 void rb_delete(int key);
17 rb_node* clock_wise(rb_node* node);
18 rb_node* counter_clock_wise(rb_node* node);
19 void show_rb_tree(rb_node* node);
20
21 rb_node* get_node(rb_node* parent, int key){
22 rb_node *tmp = (rb_node*)malloc(sizeof(rb_node));
23 tmp->key = key;
24 tmp->colour = RED;
25 tmp->parent = parent;
26 tmp->lchild = tmp->rchild = NULL;
27 return tmp;
28 }
29
30 rb_node* clock_wise(rb_node* node){
31 if(node == NULL || node->lchild == NULL)
32 return NULL;
33
34 rb_node *rb_1=node, *rb_2=node->lchild, *rb_3=node->lchild->rchild;
35 if(rb_1->parent != NULL){
36 if(rb_1->parent->lchild == rb_1)
37 rb_1->parent->lchild = rb_2;
38 else
39 rb_1->parent->rchild = rb_2;
40 }else if(rb_1 == root){
41 root = rb_2;
42 }
43 rb_2->parent = rb_1->parent;
44
45 rb_1->parent = rb_2;
46 rb_2->rchild = rb_1;
47
48 rb_1->lchild = rb_3;
49 if(rb_3 != NULL)rb_3->parent = rb_1;
50
51 return rb_2;
52 }
53
54 rb_node* counter_clock_wise(rb_node* node){
55 if(node == NULL || node->rchild == NULL)
56 return NULL;
57
58 rb_node *rb_1=node, *rb_2=node->rchild, *rb_3=node->rchild->lchild;
59 if(rb_1->parent != NULL){
60 if(rb_1->parent->lchild == rb_1)
61 rb_1->parent->lchild = rb_2;
62 else
63 rb_1->parent->rchild = rb_2;
64 }
65 else if(rb_1 == root){
66 root = rb_2;
67 }
68 rb_2->parent = rb_1->parent;
69
70 rb_1->parent = rb_2;
71 rb_2->lchild = rb_1;
72
73 rb_1->rchild = rb_3;
74 if(rb_3 != NULL)rb_3->parent = rb_1;
75
76 return rb_2;
77 }
78
79 rb_node* rb_search(int key){
80 rb_node *p = root;
81 while(p != NULL){
82 if(key < p->key)
83 p = p->lchild;
84 else if(key > p->key)
85 p = p->rchild;
86 else
87 break;
88 }
89 return p;
90 }
91
92 void rb_insert(int key){
93 rb_node *p=root, *q=NULL;
94
95 if(root == NULL){
96 root = get_node(NULL, key);
97 root->colour = BLACK;
98 return;
99 }
100
101 while(p != NULL){
102 q = p;
103 if(key < p->key)
104 p = p->lchild;
105 else if(key > p->key)
106 p = p->rchild;
107 else return;
108 }
109
110 if(key < q->key)
111 q->lchild = get_node(q, key);
112 else
113 q->rchild = get_node(q, key);
114
115 while(q != NULL && q->colour == RED){
116 p = q->parent;//p won't null, or BUG.
117
118 if(p->lchild == q){
119 if(q->rchild != NULL && q->rchild->colour == RED)
120 counter_clock_wise(q);
121 q = clock_wise(p);
122 q->lchild->colour = BLACK;
123 }
124 else{
125 if(q->lchild != NULL && q->lchild->colour == RED)
126 clock_wise(q);
127 q = counter_clock_wise(p);
128 q->rchild->colour = BLACK;
129 }
130
131 q = q->parent;
132 }
133 root->colour = BLACK;
134 }
135
136 void show_rb_tree(rb_node* node){
137 if(node == NULL)
138 return;
139 printf("(%d,%d)\n", node->key, node->colour);
140 if(node->lchild != NULL){
141 printf("[-1]\n");
142 show_rb_tree(node->lchild);
143 }
144 if(node->rchild != NULL){
145 printf("[1]\n");
146 show_rb_tree(node->rchild);
147 }
148 printf("[0]\n");
149 }
150
151 void rb_delete(int key){
152 rb_node *v = rb_search(key), *u, *p, *c, *b;
153 int tmp;
154 if(v == NULL) return;
155
156 u = v;
157 if(v->lchild != NULL && v->rchild != NULL){
158 u = v->rchild;
159 while(u->lchild != NULL){
160 u = u->lchild;
161 }
162 tmp = u->key;
163 u->key = v->key;
164 v->key = tmp;
165 }
166
167 //u is the node to free.
168 if(u->lchild != NULL)
169 c = u->lchild;
170 else
171 c = u->rchild;
172
173 p = u->parent;
174 if(p != NULL){
175 //remove u from rb_tree.
176 if(p->lchild == u)
177 p->lchild = c;
178 else
179 p->rchild = c;
180 }
181 else{
182 //u is root.
183 root = c;
184 free((void*)u);
185 return;
186 }
187
188 //u is not root and u is RED, this will not unbalance.
189 if(u->colour == RED){
190 free((void*)u);
191 return;
192 }
193
194 free((void*)u);
195 u = c;
196
197 //u is the first node to balance.
198 while(u != root){
199 if(u != NULL && u->colour == RED){
200 //if u is RED, change it to BLACK can finsh.
201 u->colour = BLACK;
202 return;
203 }
204
205 if(u == p->lchild)
206 b = p->rchild;
207 else
208 b = p->lchild;
209
210 printf("%d\n", b->key);
211
212 //b is borther of u. b can't be null, or the rb_tree is must not balance.
213 if(b->colour == BLACK){
214 //If b's son is RED, rotate the node.
215 if(b->lchild != NULL && b->lchild->colour == RED){
216 if(u == p->lchild){
217 b = clock_wise(b);
218 b->colour = BLACK;
219 b->rchild->colour = RED;
220
221 p = counter_clock_wise(p);
222 p->colour = p->lchild->colour;
223 p->lchild->colour = BLACK;
224 p->rchild->colour = BLACK;
225 }
226 else{
227 p = clock_wise(p);
228 p->colour = p->rchild->colour;
229 p->rchild->colour = BLACK;
230 p->lchild->colour = BLACK;
231 }
232
233 return;
234 }
235 else if(b->rchild != NULL && b->rchild->colour == RED){
236 if(u == p->rchild){
237 b = counter_clock_wise(b);
238 b->colour = BLACK;
239 b->lchild->colour = RED;
240
241 p = clock_wise(p);
242 p->colour = p->rchild->colour;
243 p->rchild->colour = BLACK;
244 p->lchild->colour = BLACK;
245 }
246 else{
247 p = counter_clock_wise(p);
248 p->colour = p->lchild->colour;
249 p->lchild->colour = BLACK;
250 p->rchild->colour = BLACK;
251 }
252 return;
253 }
254 else{//if b's sons are BLACK, make b RED and move up u.
255 b->colour = RED;
256 u = p;
257 p = u->parent;
258 continue;
259 }
260 }
261 else{
262 if(u == p->lchild){
263 p = counter_clock_wise(p);
264 p->colour = BLACK;
265 p->lchild->colour = RED;
266 p = p->lchild;
267 }
268 else{
269 p = clock_wise(p);
270 p->colour = BLACK;
271 p->rchild->colour = RED;
272 p = p->rchild;
273 }
274 }
275 }
276 root->colour = BLACK;
277 }
278
279 int main(){
280 int i;
281 root = NULL;
282 for(i = 1; i <= 10; i++){
283 rb_insert(i);
284 }
285 rb_delete(9);
286 rb_delete(3);
287 rb_delete(7);
288 show_rb_tree(root);
289 printf("\n");
290 return 0;
291 }
原文地址:https://www.cnblogs.com/ggzwtj/p/2190420.html