zoukankan      html  css  js  c++  java
  • .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
    ");
            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

  • 相关阅读:
    了解linux web的监听工具
    Ubuntu 16.04 安装docker-ce,docker-compose
    php 连接mysql 主机 localhost,显示 No such file or directory
    vagrant ssh try
    解决 WordPress“正在执行例行维护,请一分钟后回来”
    wordpress Warning: Parameter 2 to qtranxf_postsFilter() expected to be a reference
    ubuntu phpize 安裝
    ubuntu 16.04 pecl 不能安裝 mcrypt
    wp api jwt 403 (Forbidden) -- JWT is not configurated properly, please contact the admin
    docker gitlab backup
  • 原文地址:https://www.cnblogs.com/shaughn/p/3488211.html
Copyright © 2011-2022 走看看