平衡二叉树

 1、平衡二叉树(AVL):它或者是一颗空树,左子树和右子树的深度之差不超过1,且他的左子树和右子树都是一颗平衡二叉树

2、平衡二叉树出现的原因:平衡二叉树就是在二叉排序树(BST)引入的,就是为了解决二叉排序树的不平衡性导致时间复杂度大大下降,AVL就保持住了BST的最好时间复杂度O(logn),所以每次插入和删除都要确保二叉树的平衡,很好的解决了二叉查找树退化成链表的问题,把插入查找删除的时间复杂度最好情况和最坏的情况都维持在了O(logn),但是频繁旋转会使插入和删除牺牲掉O(logn)左右的时间,相对二叉查找树来说,时间上稳定了很多。

3、平衡二叉树默认左孩子的值比双亲节点小,右孩子的值比双亲节点大(这句话也很重要)。由此在插入或者删除结点时,如何调整二叉树为平衡二叉树?这里就有四种情况

  1、去判断每个结点的平衡因子,为2的结点要移动,如果一棵树有两个结点平衡因子都为2,移动下面的那个结点(这句话很重要)

  LL:首先这个图的大小排序你能分辨出来吗:T1<Z<T2<X<T3<Y<T4(如果能分辨出来,以下内容你将会很好理解)

    这是所谓的左左结构:x<y x>z 所以不平衡时把x放在中间,T3>X T3<Y 所以T3应该放在X的右边,Y的左边

    

 

  LR:一样的道理z>x z<y 所以Z应该放在x、y的中间,T2>x T2<z; T3>zT3<y

             

  RR:x放在y和z的中间,T3<x,T3>y

                

  RL:  Z<X Z>Y 所以z放在xy中间, T2>Y,T2<Z; T3>Z,T3<X

             

4、那既然说完上面的四种调整结构了,如何使用呢,用插入元素(90,66,65,98,100,88,105,102,110,103)构造一颗平衡二叉树,构造过程如下

          

          

               

5、既然插入说了,此处相信大家删除结点在调整为平衡二叉树一定会了吧,就不一一举例了

可运行代码

复制代码
 1 #ifndef BINARY_H
 2 #define BINARY_H
 3 
 4 typedef int TYPE;
 5 typedef int BOOL;
 6 
 7 typedef struct _BTNode
 8 {
 9     TYPE data;
10     int height;
11     struct _BTNode *lchild;
12     struct _BTNode *rchild;
13 } BTNode;
14 
15 typedef struct _BTree
16 {
17     BTNode *phead;
18 
19     void (*init)(struct _BTree *BT, TYPE head_value);
20     void (*exit)(struct _BTree *BT);
21     void (*print)(struct _BTree *BT, BTNode *phead);
22 
23     BOOL(*add)
24     (struct _BTree *BT, BTNode *phead, TYPE value);
25     BOOL(*del)
26     (struct _BTree *BT, BTNode **phead, TYPE value);
27     BOOL(*del_tree)
28     (struct _BTree *BT, BTNode **phead);
29     BOOL(*alter)
30     (struct _BTree *BT, BTNode *phead, TYPE value,TYPE new_vlue);
31     BTNode *(*search)(struct _BTree *BT, BTNode *phead, TYPE value);
32 
33     BTNode *(*search_min)(struct _BTree *BT, BTNode **phead, int flag);
34     BTNode *(*search_max)(struct _BTree *BT, BTNode **phead, int flag);
35 
36     void (*pre_traverse)(struct _BTree *BT, BTNode *phead);
37     void (*mid_traverse)(struct _BTree *BT, BTNode *phead);
38     void (*last_traverse)(struct _BTree *BT, BTNode *phead);
39 
40     // 实现AVL所需函数
41     int (*node_height)(struct _BTree *BT, BTNode *phead);
42     void (*height)(struct _BTree *BT, BTNode *phead);
43     int (*max_height)(int height1, int height2);
44     BTNode *(*singleRotateLL)(struct _BTree *BT, BTNode *phead);
45     BTNode *(*singleRotateRR)(struct _BTree *BT, BTNode *phead);
46     BTNode *(*doubleRotateLR)(struct _BTree *BT, BTNode *phead);
47     BTNode *(*doubleRotateRL)(struct _BTree *BT, BTNode *phead);
48 } BTree;
49 
50 void tree_init(BTree *BT, TYPE value);
51 void tree_exit(BTree *BT);
52 
53 #endif
.h
复制代码
复制代码
  1 #include <stdio.h>
  2 #include <string.h>
  3 #include <stdlib.h>
  4 
  5 #include "binary.h"
  6 
  7 void tree_init(BTree *BT, TYPE head_value);
  8 void tree_exit(BTree *BT);
  9 void tree_print(BTree *BT, BTNode *phead);
 10 static BOOL tree_add(BTree *BT, BTNode *phead, TYPE value);
 11 static BOOL tree_del(BTree *BT, BTNode **phead, TYPE value);
 12 static BOOL tree_del_tree(BTree *BT, BTNode **phead);
 13 static BOOL tree_alter(BTree *BT, BTNode *phead, TYPE value, TYPE new_value);
 14 static BTNode *tree_search(BTree *BT, BTNode *phead, TYPE value);
 15 static BTNode *tree_search_min (BTree *BT, BTNode **phead, int flag);
 16 static BTNode *tree_search_max (BTree *BT, BTNode **phead,int flag);
 17 static void tree_pre_traverse(BTree *BT, BTNode *phead);
 18 static void tree_mid_traverse(BTree *BT, BTNode *phead);
 19 static void tree_last_traverse(BTree *BT, BTNode *phead);
 20 
 21 // 实现AVL所需函数
 22 static int tree_node_height(BTree *BT, BTNode *phead);
 23 static void tree_height(BTree *BT, BTNode *phead);
 24 static int max_height(int height1, int height2);
 25 static BTNode *singleRotateLL(BTree *BT, BTNode *phead);
 26 static BTNode *singleRotateRR(BTree *BT, BTNode *phead);
 27 static BTNode *doubleRotateLR(BTree *BT, BTNode *phead);
 28 static BTNode *doubleRotateRL(BTree *BT, BTNode *phead);
 29 
 30 // 初始化
 31 void tree_init(BTree *BT, TYPE head_value)
 32 {
 33     BT->phead = (BTNode*)calloc(1, sizeof(BTNode));
 34     BT->phead->data = head_value;
 35 
 36     BT->phead->lchild = BT->phead->rchild = NULL;
 37 
 38     BT->add = tree_add; //??不是很懂
 39     BT->del = tree_del;
 40     BT->print = tree_print;
 41     BT->del_tree = tree_del_tree;
 42     BT->alter = tree_alter;
 43     BT->search = tree_search;
 44     BT->search_min = tree_search_min;
 45     BT->search_max = tree_search_max;
 46     BT->pre_traverse = tree_pre_traverse;
 47     BT->mid_traverse = tree_mid_traverse;
 48     BT->last_traverse = tree_last_traverse;
 49     BT->exit = tree_exit;
 50 
 51     BT->node_height = tree_node_height;
 52     BT->height = tree_height;
 53     BT->max_height = max_height;
 54     BT->singleRotateRR = singleRotateRR;
 55     BT->singleRotateLL = singleRotateLL;
 56     BT->doubleRotateLR = doubleRotateLR;
 57     BT->doubleRotateRL = doubleRotateRL;
 58 }
 59 
 60 // 结束操作
 61 void tree_exit(BTree *BT)
 62 {
 63     if (BT != NULL)
 64     {
 65         BT->del_tree(BT, &BT->phead);
 66     }
 67 }
 68 void tree_print(BTree *BT, BTNode *phead)
 69 {
 70     if (phead != NULL)
 71     {
 72         printf("%d\n", phead->data); // 打印头结点?
 73     }
 74 }
 75 static BOOL tree_add(BTree *BT, BTNode *phead, TYPE value)
 76 { // 按序插入结点
 77     if (phead == NULL)
 78     {
 79         return 0;
 80     }
 81     if (phead->data == value) // 嗯哼?
 82     {
 83         return 0;
 84     }
 85     else
 86     {
 87         if (phead->data > value)
 88         {
 89             if (phead->lchild == NULL)
 90             {
 91                 BTNode *newnode = (BTNode *)calloc(1, sizeof(BTNode));
 92                 newnode->data = value;
 93                 newnode->lchild = newnode->rchild = NULL;
 94                 phead->lchild = newnode;
 95             }
 96             else
 97             {
 98                 tree_add(BT, phead->lchild, value);
 99 
100                 // 判断插入结点后是否平衡,并调整
101                 BTNode *root;
102                 if (phead = BT->phead) //>是否写的不对
103                 {
104                     root = phead;
105                 }
106                 else
107                 {
108                     root = phead->lchild;
109                 }
110                 if (tree_node_height(BT, root->lchild) - tree_node_height(BT, root->rchild) == 2)
111                 {
112                     if (root->lchild->data > value)
113                     {
114                         root = singleRotateLL(BT, root);
115                     }
116                     else
117                     {
118                         root = doubleRotateLR(BT, root);
119                     }
120                 }
121                 phead = root;
122             }
123         }
124         else
125         {
126             if (phead->rchild == NULL)
127             {
128                 BTNode *newnode = (BTNode *)calloc(1, sizeof(BTNode));
129                 newnode->data = value;
130                 newnode->lchild = newnode->rchild = NULL;
131                 phead->rchild = newnode;
132             }
133             else
134             {
135                 tree_add(BT, phead->rchild, value);
136 
137                 // 判断插入结点是否平衡,并调整
138                 BTNode *root;
139                 if (phead = BT->phead)
140                 {
141                     root = phead;
142                 }
143                 else
144                 {
145                     root = phead->rchild;
146                 }
147                 if (tree_node_height(BT, root->rchild) - tree_node_height(BT, root->lchild) == 2)
148                 {
149                     if (root->rchild->data < value)
150                     {
151                         root = singleRotateRR(BT, root);
152                     }
153                     else
154                     {
155                         root = doubleRotateRL(BT, root);
156                     }
157                 }
158                 phead = root;
159             }
160         }
161         phead->height = tree_node_height(BT, phead);
162         return 1;
163     }
164     return 0;
165 }
166 
167 // 删除结点
168 static BOOL tree_del(BTree *BT, BTNode **phead, TYPE value)
169 {
170     BTNode *temp;
171     BTNode *root;
172     int flag;//标记结点,顶部结点为0,左边节点为-1,右边结点为1;
173 
174     if(*phead == NULL)
175     {
176         return 0;
177     }
178 
179     if (*phead == BT->phead)
180     {
181         flag = 0;
182         root = *phead;
183     }
184     else if ((*phead)->lchild != NULL)
185     {
186         flag = -1;
187         root = (*phead)->lchild;
188     }
189     else if ((*phead)->rchild != NULL)
190     {
191         flag = 1;
192         root = (*phead)->rchild;
193     }
194     else if ((*phead)->lchild == NULL && (*phead)->rchild == NULL)
195     {
196         root = *phead;
197     }
198     if (root->data == value)
199     {
200         if (root->lchild != NULL)
201         {
202             temp = BT->search_max(BT, &root->lchild, 1);
203             temp->lchild = root->lchild;
204             temp->rchild = root->rchild;
205             free(root);
206             root = temp;
207             if (flag == 0)
208             {
209                 BT->phead = root;
210             }
211             else
212             {
213                 (*phead)->lchild = root;
214             }
215         }
216         else if (root->rchild != NULL)
217         {
218             temp = BT->search_min(BT, &root->rchild, 1);
219             temp->lchild = root->lchild;
220             temp->rchild = root->rchild;
221             free(root);
222             root = temp;
223             if (flag == 0)
224             {
225                 BT->phead = root;
226             }
227             else
228             {
229                 (*phead)->rchild = root;
230             }
231         }
232         else 
233         {
234             if (flag == 0)
235             {
236                 free(*phead);
237             }
238             else if (flag = -1)
239             {
240                 free((*phead)->lchild);
241                 (*phead)->lchild = NULL;
242             }
243             else if (flag = 1)
244             {
245                 free((*phead)->rchild);
246                 (*phead)->rchild = NULL;
247             }
248         }
249 
250         tree_height(BT, BT->phead);//删除结点,求节点的新高度
251 
252         if (flag == 0)
253         {
254             return 1;
255         }
256         if (flag == -1)
257         {
258             if (tree_node_height(BT, (*phead)->rchild) - tree_node_height(BT, (*phead)->lchild) == 2)
259             {
260                 if ((*phead)->rchild->rchild != NULL)
261                 {
262                     root = singleRotateRR(BT, *phead);
263                 }
264                 else
265                 {
266                     root = doubleRotateRL(BT, *phead);
267                 }
268             }
269          }
270         else
271         {
272             if (tree_node_height(BT, (*phead)->lchild) - tree_node_height(BT, (*phead)->rchild) == 2)
273             {
274                 if ((*phead)->lchild->lchild != NULL)
275                 {
276                     root = singleRotateLL(BT, *phead);
277                 }
278                 else
279                 {
280                     root = doubleRotateLR(BT, *phead);
281                 }
282             }
283         }
284         return 1;
285         
286     }
287     else if (root->data > value)
288     {
289         return BT->del(BT, &root->lchild, value);
290     }
291     else
292     {
293         return BT->del(BT, &root->rchild, value);
294     }
295 
296     return 0;
297 }
298 
299 // 删除二叉树
300 static BOOL tree_del_tree(BTree *BT, BTNode **phead)
301 {
302     if (*phead == NULL)
303     {
304         return 0;
305     }
306     if ((*phead)->lchild != NULL)
307     {
308         BT->del_tree(BT, &(*phead)->lchild);
309     }
310     if ((*phead)->rchild != NULL)
311     {
312         BT->del_tree(BT, &(*phead)->rchild);
313     }
314     free(*phead);
315     *phead = NULL;
316 
317     return 1;
318 }
319 
320 // 更改结点的值(先删除,后插入)
321 static BOOL tree_alter(BTree *BT, BTNode *phead, TYPE value, TYPE new_value)
322 {
323     if (phead == NULL)
324     {
325         return 0;
326     }
327     if (value == new_value)
328     {
329         return 1;
330     }
331     if (BT->del(BT, &phead, value) != 0)
332     {
333         if (BT->add(BT, phead, new_value) != 0)
334         {
335             return 1;
336         }
337         else
338         {
339             return 0;
340         }
341     }
342     else
343     {
344         return 0;
345     }
346 }
347 
348 // 查找结点
349 static BTNode *tree_search(BTree *BT, BTNode *phead, TYPE value)
350 {
351     BTNode *temp;
352 
353     if (phead == NULL)
354     {
355         return NULL;
356     }
357     if (phead->data == value)
358     {
359         return phead;
360     }
361     if (phead->lchild != NULL)
362     {
363         temp = BT->search(BT, phead->lchild, value);
364         if (temp != NULL)
365         {
366             return temp;
367         }
368     }
369     if (phead->rchild != NULL)
370     {
371         temp = BT->search(BT, phead->rchild, value);
372         
373             if (temp != NULL)
374             {
375                 return temp;
376             }
377     }
378     return NULL;
379 }
380 
381 // 查找最小结点
382 static BTNode *tree_search_min(BTree *BT, BTNode **phead, int flag)
383 {
384     BTNode *temp;
385 
386     if (*phead == NULL)
387     {
388         return NULL;
389     }
390 
391     if ((*phead)->lchild == NULL) // 咩看懂
392     {
393         temp = *phead;
394         if (flag == 1)
395         {
396             *phead = (*phead)->rchild;
397         }
398         return temp;
399     }
400     else
401     {
402         return BT->search_min(BT, &(*phead)->lchild, flag); // 平衡二叉树一直往左找最小值
403     }
404 }
405 
406 // 查找最大节点
407 static BTNode *tree_search_max(BTree *BT, BTNode **phead, int flag)
408 {
409     BTNode *temp;
410 
411     if (*phead == NULL)
412     {
413         return NULL;
414     }
415 
416     if ((*phead)->lchild == NULL) // 咩看懂
417     {
418         temp = *phead;
419         if (flag == 1)
420         {
421             *phead = (*phead)->lchild;
422         }
423         return temp;
424     }
425     else
426     {
427         return BT->search_min(BT, &(*phead)->rchild, flag); // 往右找最大值
428     }
429 }
430 
431 // 先序遍历二叉树
432 static void tree_pre_traverse(BTree *BT, BTNode *phead)
433 {
434     if (phead == NULL)
435     {
436         return;
437     }
438     BT->print(BT, phead);
439     if (phead->lchild != NULL)
440     {
441         BT->pre_traverse(BT, phead->lchild); // 觉得BT指向很奇怪
442     }
443     if (phead->rchild != NULL)
444     {
445         BT->pre_traverse(BT, phead->rchild);
446     }
447 }
448 
449 // 中序遍历二叉树
450 static void tree_mid_traverse(BTree *BT, BTNode *phead)
451 {
452     if (phead == NULL)
453     {
454         return;
455     }
456     if (phead->lchild != NULL)
457     {
458         BT->mid_traverse(BT, phead->lchild);
459     }
460     BT->print(BT, phead);
461     if (phead->rchild != NULL)
462     {
463         BT->mid_traverse(BT, phead->rchild);
464     }
465 }
466 
467 // 后续遍历二叉树
468 static void tree_last_traverse(BTree *BT, BTNode *phead)
469 {
470     if (phead == NULL)
471     {
472         return;
473     }
474 
475     if (phead->lchild != NULL)
476     {
477         BT->last_traverse(BT, phead->lchild);
478     }
479     if (phead->rchild != NULL)
480     {
481         BT->last_traverse(BT, phead->rchild);
482     }
483     BT->print(BT, phead);
484 }
485 
486 // 求结点的高度,写成函数解决指针为空的情况,默认空节点的高度为-1,只有一个根节点的高度为0,多一层高度加一
487 static int tree_node_height(BTree *BT, BTNode *phead)
488 {
489     if (phead != NULL)
490     {
491         if (phead->lchild == NULL && phead->rchild == NULL)
492         {
493             return 0;
494         }
495         else
496         {
497             return phead->height = max_height((tree_node_height(BT, phead->lchild)), (tree_node_height(BT, phead->rchild))) + 1;
498         }
499     }
500     else
501     {
502         return -1;
503     }
504 }
505 
506 // 遍历求树中每个节点的高度
507 static void tree_height(BTree *BT, BTNode *phead)
508 {
509     if (phead == NULL)
510     {
511         return;
512     }
513     tree_node_height(BT, phead);
514     if (phead->lchild != NULL)
515     {
516         tree_node_height(BT, phead->lchild);
517     }
518     if (phead->rchild != NULL)
519     {
520         tree_node_height(BT, phead->rchild);
521     }
522 }
523 
524 // 求两个高度的最大值
525 static int max_height(int height1, int height2)
526 {
527     if (height1 > height2)
528     {
529         return height1;
530     }
531     else
532     {
533         return height2;
534     }
535 }
536 
537 // 左左情况
538 static BTNode *singleRotateLL(BTree *BT, BTNode *phead)
539 {
540     BTNode *temp;
541     if (phead == NULL)
542     {
543         return 0;
544     }
545     temp = phead->lchild;
546 
547     if (temp->rchild != NULL)
548     {
549         phead->lchild = temp->rchild;
550         phead->lchild->height = tree_node_height(BT, phead->lchild);
551     }
552     else
553     {
554         phead->lchild = NULL;
555     }
556 
557     temp->rchild = phead;
558     if (temp->rchild->data == BT->phead->data)
559     {
560         BT->phead = temp;
561     }
562     phead = temp;
563     temp->rchild->height = tree_node_height(BT, temp->rchild);
564     temp->height = tree_node_height(BT, temp);
565     phead->height = tree_node_height(BT, phead);
566 
567     return phead;
568 }
569 
570 // 右右
571 static BTNode *singleRotateRR(BTree *BT, BTNode *phead)
572 {
573     BTNode *temp;
574     if (phead == NULL)
575     {
576         return 0;
577     }
578     temp = phead->rchild;
579 
580     if (temp->lchild != NULL)
581     {
582         phead->rchild = temp->lchild;
583         phead->rchild->height = tree_node_height(BT, phead->rchild);
584     }
585     else
586     {
587         phead->rchild = NULL;
588     }
589     temp->lchild = phead;
590     if (temp->lchild->data == BT->phead->data)
591     {
592         BT->phead = temp;
593     }
594     phead = temp;
595     temp->lchild->height = tree_node_height(BT, temp->lchild);
596     temp->height = tree_node_height(BT, temp);
597     phead->height = tree_node_height(BT, phead);
598 
599     return phead;
600 }
601 
602 static BTNode *doubleRotateLR(BTree *BT, BTNode *phead)
603 {
604     BTNode *temp;
605     if (phead == NULL)
606     {
607         return 0;
608     }
609     temp = phead->lchild;
610     phead->lchild = singleRotateRR(BT, temp);
611     temp = phead;
612     phead = singleRotateLL(BT, temp);
613 
614     return phead;
615 }
616 
617 static BTNode *doubleRotateRL(BTree *BT, BTNode *phead)
618 {
619     BTNode *temp;
620     if (phead == NULL)
621     {
622         return 0;
623     }
624     temp = phead->rchild;
625     phead->rchild = singleRotateLL(BT, temp);
626     temp = phead;
627     phead = singleRotateRR(BT, temp);
628 
629     return phead;
630 }
631 
632 int main()
633 {
634     BTree testtree;
635     testtree.init = tree_init;
636     testtree.init(&testtree,9);
637 
638     testtree.add(&testtree,testtree.phead,4);
639     testtree.add(&testtree,testtree.phead,5);
640     testtree.add(&testtree,testtree.phead,6);
641     testtree.add(&testtree,testtree.phead,1);
642     testtree.add(&testtree,testtree.phead,7);
643     testtree.add(&testtree,testtree.phead,8);
644     testtree.add(&testtree,testtree.phead,11);
645     testtree.add(&testtree,testtree.phead,10);
646 
647     testtree.pre_traverse(&testtree,testtree.phead);
648     printf("\n");
649     testtree.mid_traverse(&testtree,testtree.phead);
650     printf("\n");
651     testtree.last_traverse(&testtree,testtree.phead);
652     printf("\n");
653     printf("%d\n",(testtree.search(&testtree,testtree.phead,8)->data));
654 //前面的可以正常运行
655 
656     testtree.alter(&testtree,testtree.phead,9,2);
657     testtree.del(&testtree,&testtree.phead,4);
658     testtree.del(&testtree,&testtree.phead,1);
659     testtree.del(&testtree,&testtree.phead,6);
660    
661 
662     testtree.pre_traverse(&testtree,testtree.phead);
663     printf("\n");
664     testtree.mid_traverse(&testtree,testtree.phead);
665     printf("\n");
666     testtree.last_traverse(&testtree,testtree.phead);
667     printf("\n");
668 
669     return 0;
670 
671 }
.c
复制代码

感谢观看

 

posted @   风中凌乱的猪头  阅读(44)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示