基本数据结构之AVL树-简单实现

一、AVL 简介

    AVL树是一种平衡的BST,关于BST,参看另一篇博文

    AVL树的平衡因子的计算公式为:factor = height(lchild) - height(rchild);

    在AVL树中,每个结点的平衡因子不超过1。在实际应用中,尽管结点的平衡因子能够通过它的子树计算出来,但是结点的平衡因子一般是存储在结点信息中的。

    在一颗包含N个结点的AVL中,平均情况和最坏情况下的-->查找、插入和删除结点的时间复杂度均为O(lgN),在BST中最坏情况下的时间复杂度为:O(N).

    在一颗AVL树中,在执行了插入或者删除操作时,你可能需要re-balance 这棵AVL树。


二、AVL的简单C实现

        1)AVL的结点结构

         

 
 
/*
the struct of the AVL tree
*/
typedef struct node {
   int data ;
   struct node * lchild ;
   struct node * rchild ;
   int height ;
} AVLnode ;

    2) 销毁给点结点的AVL

 
 
void dispose ( AVLnode * node )
{
   if ( ! node )
      return ;
   dispose ( node -> lchild );
   dispose ( node -> rchild );
   free ( node );
}

   3)查找指定的结点

 
 
AVLnode * search ( int e , AVLnode * node )
{
   if ( ! node )
     return NULL ;
   if ( e == node -> data )
     return node ;
   if ( e < node -> data )
     return search ( node -> lchild , e );
   else
     return search ( node -> rchild , e );
}
  

  4)查找最大的结点

 
 
AVLnode * max_node ( const AVLnode * node )
{
   if ( ! node )
     return NULL ;
   while ( node -> rchild )
     node = node -> rchild ;
  
   return ( AVLnode * ) node ;
}
 

  5)查找最小的结点

 
 
AVLnode * min_node ( const AVLnode * node )
{
   if ( ! node )
     return NULL ;
   while ( node -> lchild )
     node = node -> lchild ;
  
   return ( AVLnode * ) node ;
}
 

6)计算给定结点的高度

 
 
static int height ( AVLnode * node )
{
   if ( NULL == node )
     return - 1 ;
   else
     return node -> height ;
}

7)返回两个整数中的较大者

 
 
static int max ( int m , int n )
{
   return m > n ? m : n ;
}

8)//接下来是AVL树的集中旋转操作

 
 
/*
case1.single rotate with left
*/
static AVLnode * single_left ( AVLnode * t )
{
   AVLnode * p = NULL ;
   if ( ! t )
     return NULL ;
   p = t -> lchild ;
   t -> lchild = p -> rchild ;
   p -> rchild = t ;
  
   t -> height = max ( height ( t -> lchild ), height ( t -> rchild )) + 1 ;
   p -> height = max ( height ( p -> lchild ), t -> height ) + 1 ;
  
   return p ; // the new root
}
/*
case2.single rotate with right
*/
static AVLnode * single_right ( AVLnode * t )
{
   AVLnode * p = NULL ;
   if ( ! t )
     return NULL ;
   p = t -> rchild ;
   t -> rchild = p -> lchild ;
   p -> lchild = t ;
  
   t -> height = max ( height ( t -> lchild ), height ( t -> rchild )) + 1 ;
   p -> height = max ( height ( p -> rchild ), t -> height ) + 1 ;
  
   return p ; // the new root
}
/*
case3.left-right double rotation
call double_left only if t node has
a left child and t's left child has a right child
*/
static double_left ( AVLnode * t )
{
   if ( ! t )
     return NULL ;
   t -> lchild = single_right ( t -> lchild );
  
   return single_left ( t );
}
/*
case4. right-left double rotation
call double_rotate_with_right only if t has a
right child and t's right child has a left child
*/
static double_right ( AVLnode * t )
{
   if ( ! t )
     return NULL ;
  
   t -> rchild = single_left ( t -> rchild );
  
   return single_right ( t );
}

9)向AVL中插入一个结点

 
 
AVLnode * insert ( int e , AVLnode * node )
{
   if ( ! node )
   {
     //create and return a one-node AVL tree
     node = ( AVLnode * ) malloc ( sizeof ( AVLnode ));
     if ( ! node )
     {
       fprintf ( stderr , "Allocate memory error!" );
       exit ( 1 );
     }
     node -> data = e ;
     node -> height = 0 ;
     node -> lchild = node -> rchild = NULL ;
   }
   else if ( e < node -> data )
   {
     node -> lchild = insert ( e , node -> lchild );
     if ( height ( node -> lchild ) - height ( node -> rchild ) == 2 )
     {
       if ( e < node -> lchild -> data )
         node = single_left ( node );
       else
         node = double_left ( node );
     }
   } else if ( e > node -> data )
   {
     node -> rchild = insert ( e , node -> rchild );
     if ( height ( node -> rchild ) - height ( node -> lchild ) == 2 )
     {
       if ( e > node -> rchild -> data )
         node = single_right ( node );
       else
         node = double_right ( node );
     }
   }
   //else the node is in the AVL tree already,we do nothing
   node -> height = max ( height ( node -> lchild ), height ( node -> rchild )) + 1 ;
   return node ;
}
10)返回给定结点的数据

 
 
/*
get the data of the specific node
*/
int get_data ( AVLnode * node )
{
   if ( ! node )
     exit ( 1 );
   return node -> data ;
}
11)打印整个AVL树

 
 
void display ( AVLnode * node )
{
   if ( ! node )
     return ;
   printf ( "%d " , node -> data );
  
   if ( node -> lchild )
     printf ( "%d " , node -> lchild -> data );
   if ( node -> rchild )
     printf ( "%d " , node -> rchild -> data );
  
   printf ( " \n " );
   display ( node -> lchild );
   display ( node -> rchild );
}

12)AVL的删除操作

 
 
AVLnode * delete ( int e , AVLnode * node )
{
  
   return node ;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值