一、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 );elsereturn 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 ;elsereturn 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 rotationcall double_left only if t node hasa 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 rotationcall double_rotate_with_right only if t has aright 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中插入一个结点
10)返回给定结点的数据AVLnode * insert ( int e , AVLnode * node ){if ( ! node ){//create and return a one-node AVL treenode = ( 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 );elsenode = 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 );elsenode = double_right ( node );}}//else the node is in the AVL tree already,we do nothingnode -> height = max ( height ( node -> lchild ), height ( node -> rchild )) + 1 ;return node ;}
11)打印整个AVL树/*get the data of the specific node*/int get_data ( AVLnode * node ){if ( ! node )exit ( 1 );return node -> data ;}
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 ;}