.8 AVL树

平衡二叉树(Balanced Binary Tree)是二叉查找树的一个进化体,也是第一个引入平衡概念的二叉树。1962年,G.M. Adelson-Velsky 和 E.M. Landis发明了这棵树,所以它又叫AVL树。平衡二叉树要求对于每一个节点来说,它的左右子树的高度之差不能超过1,如果插入或者删除一个节点使得高度之差大于1,就要进行节点之间的旋转,将二叉树重新维持在一个平衡状态。这个方案很好的解决了二叉查找树退化成链表的问题,把插入,查找,删除的时间复杂度最好情况和最坏情况都维持在O(logN)。但是频繁旋转会使插入和删除牺牲掉O(logN)左右的时间,不过相对二叉查找树来说,时间上稳定了很多。

(1)左左  (2)左右  (3)右左  (4)右右

     

       对于“左左”“右右”的情况,只要进行一次单旋转就可以使其恢复平衡。如下图:

       

相应的给出代码:

 

[cpp] view plaincopy
 
  1. //左左  
  2. TreeNode *SingleRotateLeft(TreeNode *t2)  
  3. {  
  4.     TreeNode *t1;  
  5.     t1 = t2->left;  
  6.         t2->left = t1->right;  
  7.     t1->right = t2;  
  8.   
  9.     t2->height = max(getHeight(t2->left),getHeight(t2->right)) + 1;  
  10.     t1->height = max(getHeight(t1->left),getHeight(t1->right)) + 1;  
  11.     return t1;  
  12. }  

 

 

[cpp] view plaincopy
 
  1. //右右  
  2.  TreeNode *SingleRotateRight(TreeNode *t2)  
  3.  {  
  4.      TreeNode *t1;  
  5.      t1 = t2->right;  
  6.      t2->right = t1->left;  
  7.      t1->left = t2;  
  8.   
  9.      t2->height = max(getHeight(t2->left),getHeight(t2->right)) + 1;  
  10.      t1->height = max(getHeight(t1->left),getHeight(t1->right)) + 1;  
  11.      return t1;  
  12.  }  


对于“左右”“右左”则要进行一次双旋转,如下图:

 

 

相应的代码:

 

[cpp] view plaincopy
 
  1. //左右  
  2. TreeNode * DoubleRotateLR(TreeNode *t3)  
  3. {  
  4.  t3->left = SingleRotateRight(t3->left);  
  5.  return SingleRotateLeft(t3);  
  6. }  


[cpp] view plaincopy
 
    1. //右左  
    2. TreeNode * DoubleRotateRL(TreeNode *t3)  
    3. {  
    4.  t3->right = SingleRotateLeft(t3->right);  
    5.  return SingleRotateRight(t3);  
    6. }  

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\n");
        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("\n") ;
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

 

posted @ 2013-12-23 22:13  shaughn  阅读(223)  评论(0编辑  收藏  举报