平衡二叉树(Balanced Binary Tree)是二叉查找树的一个进化体,也是第一个引入平衡概念的二叉树。1962年,G.M. Adelson-Velsky 和 E.M. Landis发明了这棵树,所以它又叫AVL树。平衡二叉树要求对于每一个节点来说,它的左右子树的高度之差不能超过1,如果插入或者删除一个节点使得高度之差大于1,就要进行节点之间的旋转,将二叉树重新维持在一个平衡状态。这个方案很好的解决了二叉查找树退化成链表的问题,把插入,查找,删除的时间复杂度最好情况和最坏情况都维持在O(logN)。但是频繁旋转会使插入和删除牺牲掉O(logN)左右的时间,不过相对二叉查找树来说,时间上稳定了很多。
(1)左左 (2)左右 (3)右左 (4)右右
对于“左左”和“右右”的情况,只要进行一次单旋转就可以使其恢复平衡。如下图:
相应的给出代码:
- //左左
- TreeNode *SingleRotateLeft(TreeNode *t2)
- {
- TreeNode *t1;
- t1 = t2->left;
- t2->left = t1->right;
- t1->right = t2;
- t2->height = max(getHeight(t2->left),getHeight(t2->right)) + 1;
- t1->height = max(getHeight(t1->left),getHeight(t1->right)) + 1;
- return t1;
- }
- //右右
- TreeNode *SingleRotateRight(TreeNode *t2)
- {
- TreeNode *t1;
- t1 = t2->right;
- t2->right = t1->left;
- t1->left = t2;
- t2->height = max(getHeight(t2->left),getHeight(t2->right)) + 1;
- t1->height = max(getHeight(t1->left),getHeight(t1->right)) + 1;
- return t1;
- }
对于“左右”和“右左”则要进行一次双旋转,如下图:
相应的代码:
- //左右
- TreeNode * DoubleRotateLR(TreeNode *t3)
- {
- t3->left = SingleRotateRight(t3->left);
- return SingleRotateLeft(t3);
- }
- //右左
- TreeNode * DoubleRotateRL(TreeNode *t3)
- {
- t3->right = SingleRotateLeft(t3->right);
- return SingleRotateRight(t3);
- }
avl.h
1 #ifndef AVL_H 2 #define AVL_H 3 4 typedef struct avlNode 5 { 6 int k ; 7 struct avlNode * lchild ,* rchild ; 8 int h ; 9 }avlnode , * avltree ; 10 11 avltree insert( avltree *T , int k ) ; 12 void del(avltree * T) ; 13 avltree search( avltree T , int k ) ; 14 avltree print( avltree T ) ; 15 void in_order_traverse( avltree T ) ; 16 #endif // AVL_H
utl.h
#ifndef UTL_H #define UTL_H #include<stdio.h> #include<stdlib.h> inline void * xalloc(int size) { void *p ; p = malloc(size) ; if(! p){ fprintf(stderr , "malloc error "); exit(EXIT_FAILURE) ; } return p ; } #define xfree(p) free(p) #endif // UTL_H
avl.c
1 #include"avl.h" 2 #include"utl.h" 3 4 int max(int a , int b ) ; 5 int height(avltree T) ; 6 7 avltree singleRotate_l(avltree T ) ; 8 avltree singleRotate_r(avltree T) ; 9 avltree doubleRotate_lr(avltree T) ; 10 avltree doubleRotate_rl(avltree T) ; 11 //void in_order_traverse(avltree T) ; 12 13 void pre_order_traverse( avltree T ) 14 { 15 if( T ){ 16 printf("%d " , T->k ) ; 17 pre_order_traverse( T->lchild ) ; 18 pre_order_traverse( T->rchild ) ; 19 } 20 } 21 22 void in_order_traverse( avltree T) 23 { 24 if(T) { 25 in_order_traverse( T->lchild ) ; 26 printf("%d " , T->k ) ; 27 in_order_traverse( T->rchild ) ; 28 } 29 } 30 31 avltree insert(avltree *T , int k) 32 { 33 if(! (*T) ) { 34 (*T) = (avltree)xalloc(sizeof(avlnode)) ; 35 (*T)->k = k ; 36 (*T)->lchild = (*T)->rchild = NULL ; 37 (*T)->h = 0 ; 38 } 39 else if( k < (*T)->k ) { 40 //插入左子树 41 (*T)->lchild = insert(&(*T)->lchild , k) ; 42 43 if( height( (*T)->lchild) - height((*T)->rchild) == 2) { //如果树不平衡 则旋转 44 if( k < (*T)->lchild->k ) { //单旋 45 (*T) = singleRotate_l( (*T) ) ; 46 } 47 else { //双旋转 48 (*T) = doubleRotate_lr( (*T) ) ; 49 } 50 } 51 52 } 53 54 else if( k > (*T)->k ) { // 插入右子树 55 (*T)->rchild = insert( &(*T)->rchild , k ) ; 56 57 if( height( (*T)->rchild) - height((*T)->lchild ) == 2) { 58 if( k > (*T)->rchild->k ) { 59 (*T) = singleRotate_r( (*T) ) ; 60 } 61 else { 62 (*T) = doubleRotate_rl( (*T) ) ; 63 } 64 } 65 } 66 67 (*T)->h = max( height( (*T)->lchild) , height( (*T)->rchild) ) + 1 ; 68 return (*T) ; 69 } 70 71 72 avltree singleRotate_l( avltree T ) 73 { 74 avltree T1 = T->lchild ; 75 T->lchild = T1->rchild ; 76 T1->rchild = T ; 77 78 T->h = max( height( T->lchild ) , height( T->rchild ) ) + 1 ; 79 T1->h = max(height( T1->lchild ) , height( T1->rchild) ) + 1 ; 80 return T1 ; 81 } 82 83 avltree singleRotate_r( avltree T) 84 { 85 avltree T1 = T->rchild ; 86 T->rchild = T1->lchild ; 87 T1->lchild = T ; 88 89 T->h = max( height( T->lchild ) , height( T->rchild ) ) +1 ; 90 T1->h = max( height( T1->lchild ) , height( T1->rchild ) ) +1 ; 91 return T1 ; 92 } 93 94 avltree doubleRotate_lr( avltree T ) 95 { 96 T->lchild = singleRotate_r( T->lchild ) ; 97 return singleRotate_l( T ) ; 98 } 99 100 avltree doubleRotate_rl( avltree T ) 101 { 102 T->rchild = singleRotate_l( T->rchild ) ; 103 return singleRotate_r( T ) ; 104 } 105 106 int max( int a , int b ) 107 { 108 return a>b?a:b ; 109 } 110 111 int height( avltree T ) 112 { 113 if(! T ) return -1 ; 114 return T->h ; 115 } 116 117 118 119 int main() 120 { 121 int i ; 122 avltree T = NULL ; 123 for(i = 0 ; i < 7 ; i++) { 124 insert( &T , i ) ; 125 } 126 in_order_traverse( T ) ; 127 printf(" ") ; 128 pre_order_traverse( T ) ; 129 return 0 ; 130 }
参考:http://blog.csdn.net/wypblog/article/details/8119616
http://blog.csdn.net/realxuejin/article/details/12872035
http://www.cppblog.com/cxiaojia/archive/2013/07/22/187776.html