1 #include<time.h>
2 #include<stdio.h>
3 #include<stdlib.h>
4 //左子树比右子树高一
5 #define LH 1
6 //左子树和右子树一样高
7 #define EH 0
8 //左子树比右子树低一
9 #define RH -1
10 #define EQ(a,b) ((a) == (b))
11 #define LT(a,b) ((a) < (b))
12 #define LQ(a,b)((a) <= (b))
13
14 typedef struct BSTNode
15 {
16 int data;
17 int bf;
18 BSTNode * lchild;
19 BSTNode * rchild;
20 }BSTNode;
21 typedef BSTNode * BSTree;
22
23 // 左旋
24 void leftRotate(BSTree & root)
25 {
26 BSTree rc = root->rchild;
27 root->rchild = rc->lchild;
28 rc->lchild = root;
29 root = rc;
30 }
31 // 右旋
32 void rightRotate(BSTree & root)
33 {
34 BSTree lc = root->lchild;
35 root->lchild = lc->rchild;
36 lc->rchild = root;
37 root = lc;
38 }
39 // 对二叉树root进行左平衡处理(LL型和LR型)
40 void leftBalance(BSTree & root)
41 {
42 BSTree lc = root->lchild;
43 switch (lc->bf)
44 {
45 //LL型的只需要进行右旋操作
46 case LH:
47 //右旋之后根和左子树都的平衡的
48 root->bf = EH;
49 lc->bf = EH;
50 //右旋操作
51 rightRotate(root);
52 break;
53 //LR型的需要进行左旋操作,然后右旋操作
54 case RH:
55 BSTree rc = lc->rchild;
56 switch (rc->bf)
57 {
58 case LH:
59 root->bf = RH;
60 lc->bf = EH;
61 break;
62 case EH:
63 root->bf = EH;
64 lc->bf = EH;
65 break;
66 case RH:
67 root->bf = EH;
68 lc->bf = LH;
69 break;
70 }
71 rc->bf = EH;
72 leftRotate(root->lchild);
73 rightRotate(root);
74 break;
75 }
76 }
77 // 功能:对二叉树root进行左平衡处理(RR型和RL型)
78 void rightBalance(BSTree & root)
79 {
80 BSTree rc = root->rchild;
81 switch (rc->bf)
82 {
83 //RR型只需要做左旋操作
84 case RH:
85 root->bf = EH;
86 rc->bf = EH;
87 //左旋操作
88 leftRotate(root);
89 break;
90 //RL型需要先做右旋操作,然后做左旋操作
91 case LH:
92 BSTree lc = rc->lchild;
93 switch (lc->bf)
94 {
95 case LH:
96 root->bf = EH;
97 rc->bf = RH;
98 break;
99 case EH:
100 root->bf = EH;
101 rc->bf = EH;
102 break;
103 case RH:
104 root->bf = LH;
105 rc->bf = EH;
106 break;
107 }
108 lc->bf = EH;
109 rightRotate(root->rchild);
110 leftRotate(root);
111 break;
112 }
113 }
114 // 功能:把元素data插入平衡二叉树root中
115 bool insert(BSTree & root, int data, bool & taller)
116 {
117 if (NULL == root)
118 {
119 root = (BSTree)malloc(sizeof(BSTNode));
120 root->rchild = NULL;
121 root->lchild = NULL;
122 root->data = data;
123 root->bf = EH;
124 taller = true;
125 }
126 else
127 {
128 //该元素已经在平衡二叉树中存在了
129 if (data == root->data)
130 {
131 taller = false;
132 return false;
133 }
134 //插入左子树
135 else if (data < root->data)
136 {
137 if (!insert(root->lchild, data, taller))
138 {
139 return false;
140 }
141 //插入成功,并且树变高了
142 if (taller)
143 {
144 switch (root->bf)
145 {
146 case LH:
147 leftBalance(root);
148 //平衡二叉树做完左平衡操作后
149 //树高没有变化,故taller = false
150 taller = false;
151 break;
152 case EH:
153 root->bf = LH;
154 //原来是平衡的故插入一个元素后
155 //树高必然变高
156 taller = true;
157 break;
158 case RH:
159 root->bf = EH;
160 //原来是右子树比左子树高,但是当向左子树中
161 //插入一个元素的时候,树变平衡了,故taller = false
162 taller = false;
163 break;
164 default:
165 break;
166 }
167 }
168 }
169 //插入右子树
170 else
171 {
172 if (!insert(root->rchild, data, taller))
173 {
174 return 0;
175 }
176 if (taller)
177 {
178 switch (root->bf)
179 {
180 case LH:
181 root->bf = EH;
182 taller = false;
183 break;
184 case EH:
185 root->bf = RH;
186 taller = true;
187 break;
188 case RH:
189 rightBalance(root);
190 taller = false;
191 break;
192 }
193 }
194 }
195 }
196 return true;
197 }
198 // 在平衡二叉树中查找int节点
199 int * search(BSTree & root, int data)
200 {
201 if (root ==NULL)
202 {
203 return NULL;
204 }
205
206 if (root->data == data)
207 {
208 return &root->data;
209 }
210 else if (data < root->data)
211 {
212 return search(root->lchild, data);
213 }
214 else
215 {
216 return search(root->rchild, data);
217 }
218 }
219 // 功能:输出平衡二叉树中的所有的元素(小->大,中序遍历)
220 void print(BSTree & root)
221 {
222 if (NULL == root)
223 {
224 return ;
225 }
226
227 print(root->lchild);
228 printf("%d ",root->data);
229 print(root->rchild);
230 }
231 // 功能:释放平衡二叉树的空间
232 void clear(BSTree & root)
233 {
234 if (NULL == root)
235 {
236 return ;
237 }
238 clear(root->lchild);
239 clear(root->rchild);
240 free(root);
241 }
242 int DeleteAVL(BSTree &T, int key, bool &shorter){
243 if (!T)
244 {//No such key
245 shorter = false;
246 return 0;
247 }
248 else
249 {
250 if (EQ(key, T->data)) //找到了需要删除的结点
251 {
252 //如果该结点的lchild 和
253 //rchild 至少有一个为NULL
254 //则大功告成,否则请参照
255 //下方解释
256 BSTree q = T;
257 if (!T->lchild)//如果该结点的lchild 为NULL
258 {
259 q = T;
260 T = T->rchild;
261 free(q);
262 shorter = true;
263 return 1;
264 }
265 else if (!T->rchild){//如果该结点的rchild 为 NULL
266 q = T;
267 T = T->lchild;//如果不是&(引用)的强大功能,这句话是没有意义的
268 free(q);
269 shorter = true;
270 return 1;
271 }
272 else {
273 //删除一个左右孩子都不为空的结点
274 //使该结点的直接前驱p的data替换该结点的data
275 //然后改变key=p.data
276 BSTree s = T->lchild;
277 while (s->rchild)
278 s = s->rchild;
279 T->data = s->data;
280 key = s->data;//Now, delete the vertice whose data was the new key
281 }
282 }
283 if (LQ(key, T->data)){//这里与InsertAVL不同
284 if (!DeleteAVL(T->lchild, key, shorter)) return 0;
285 if (shorter){
286 switch(T->bf){
287 case LH:T->bf = EH; shorter = true;break;
288 case EH:T->bf = RH;shorter = false;break;
289 case RH:rightBalance(T);
290 if (T->rchild->bf == EH)
291 shorter = false;
292 else
293 shorter = true;break;
294 }
295 }
296 }
297 else{
298 if (!DeleteAVL(T->rchild, key, shorter)) return 0;
299 if (shorter){
300 switch(T->bf){
301 case LH:leftBalance(T);
302 if (T->lchild->bf == EH)
303 shorter = false;
304 else
305 shorter = true;break;
306 case EH:T->bf = LH; shorter = false;break;
307 case RH:T->bf = EH;shorter = true;break;
308 }
309 }
310 }
311 }
312 return 1;
313 }//Delete
314 void menu()
315 {
316 printf("⊙☆⊙ ⊙☆⊙ ⊙☆⊙ ⊙☆⊙ 主菜单 ⊙☆⊙ ⊙☆⊙ ⊙☆⊙ ⊙☆⊙\n");
317 printf("⊙☆⊙ ⊙☆⊙ ⊙☆⊙请按№ 1:连续插入数据 输入0结束插入⊙☆⊙ ⊙☆⊙ ⊙☆⊙\n");
318 printf("⊙☆⊙ ⊙☆⊙ ⊙☆⊙请按№ 2:查找数据 ⊙☆⊙ ⊙☆⊙ ⊙☆⊙\n");
319 printf("⊙☆⊙ ⊙☆⊙ ⊙☆⊙请按№ 3删除特定数据 ⊙☆⊙ ⊙☆⊙ ⊙☆⊙\n");
320 printf("⊙☆⊙ ⊙☆⊙ ⊙☆⊙请按№ 4输出当前结果 ⊙☆⊙ ⊙☆⊙ ⊙☆⊙\n");
321 printf("⊙☆⊙ ⊙☆⊙ ⊙☆⊙请按№ 5结束程序 ⊙☆⊙ ⊙☆⊙ ⊙☆⊙\n");
322 }
323 int main()
324 {
325 BSTree root = NULL;
326 int num,n;
327 bool taller = false,shorter;
328 system("color 2e");
329 menu();
330 while(1)
331 {
332 scanf("%d",&num);
333 //if(num==5) break;
334 switch (num)
335 {
336 case 1:
337 system("cls");
338 printf("请插入数据 ,输入0结束插入\n");
339 while(scanf("%d",&n))
340 {
341 if(n==0) break;
342 else insert(root,n,taller);
343 }
344 system("cls");
345 menu();
346 break;
347 case 2:
348 system("cls");
349 printf("请输入要查询的数\n");
350 scanf("%d",&n);
351 int *p;
352 p=search(root,n);
353 if (p==NULL)
354 {
355 printf("对不起 没有找到 %d!\n",n);
356 }
357 else
358 {
359 printf("恭喜你 数据中存在 %d!\n",n);
360 }
361 menu();
362 break;
363 case 3:
364 system("cls");
365 printf("请输入要删除的数据\n");
366 scanf("%d",&n);
367 DeleteAVL(root,n,shorter);
368 menu();
369 break;
370 case 4:
371 system("cls");
372 print(root);
373 printf("输入0进入主菜单\n");
374 scanf("%d",&n);
375 if(!n)
376 menu();
377 break;
378 case 5:
379 clear(root);
380 return 0;
381 }
382 }
383 return 0;
384 }
原文转自:http://blog.csdn.net/hnust_xiehonghao/article/details/7938869
来源:https://www.cnblogs.com/10jschen/archive/2012/09/04/2669935.html