#include "avltree.h"
#include "fatal.h"
#include <stdlib.h>
{
ElementType Element;
AvlTree Left;
AvlTree Right;
int Height;
};
AvlTree
MakeEmpty( AvlTree T )
{
if( T != NULL )
{
MakeEmpty( T->Left );
MakeEmpty( T->Right );
free( T );
}
return NULL;
}
Position
Find( ElementType X, AvlTree T )
{
if( T == NULL )
return NULL;
if( X < T->Element )
return Find( X, T->Left );
else if( X > T->Element )
return Find( X, T->Right );
else
return T;
}
Position
FindMin( AvlTree T )
{
if( T == NULL )
return NULL;
else if( T->Left == NULL )
return T;
else
return FindMin( T->Left );
}
Position
FindMax( AvlTree T )
{
if( T != NULL )
while( T->Right != NULL )
T = T->Right;
return T;
}
/* START: fig4_36.txt */
static int
Height( Position P )
{
if( P == NULL )
return -1;
else
return P->Height;
}
/* END */
static int
Max( int Lhs, int Rhs )
{
return Lhs > Rhs ? Lhs : Rhs;
}
/* START: fig4_39.txt */
/* This function can be called only if K2 has a left child */
/* Perform a rotate between a node (K2) and its left child */
/* Update heights, then return new root */
static Position
SingleRotateWithLeft( Position K2 ) // LL
{
//printf("SingleRotateWithLeft \n");
Position K1;
K1 = K2->Left;
K2->Left = K1->Right;
K1->Right = K2;
K2->Height = Max( Height( K2->Left ), Height( K2->Right ) ) + 1;
K1->Height = Max( Height( K1->Left ), K2->Height ) + 1;
return K1; /* New root */
}
/* END */
/* This function can be called only if K1 has a right child */
/* Perform a rotate between a node (K1) and its right child */
/* Update heights, then return new root */
static Position
SingleRotateWithRight( Position K1 ) //RR
{
//printf("SingleRotateWithRight \n");
Position K2;
K2 = K1->Right;
K1->Right = K2->Left;
K2->Left = K1;
K1->Height = Max( Height( K1->Left ), Height( K1->Right ) ) + 1;
K2->Height = Max( Height( K2->Right ), K1->Height ) + 1;
return K2; /* New root */
}
/* START: fig4_41.txt */
/* This function can be called only if K3 has a left */
/* child and K3's left child has a right child */
/* Do the left-right double rotation */
/* Update heights, then return new root */
static Position
DoubleRotateWithLeft( Position K3 ) // LR
{
/* Rotate between K1 and K2 */
K3->Left = SingleRotateWithRight( K3->Left );
/* Rotate between K3 and K2 */
return SingleRotateWithLeft( K3 );
}
/* END */
/* This function can be called only if K1 has a right */
/* child and K1's right child has a left child */
/* Do the right-left double rotation */
/* Update heights, then return new root */
static Position
DoubleRotateWithRight( Position K1 ) //RL
{
/* Rotate between K3 and K2 */
K1->Right = SingleRotateWithLeft( K1->Right );
/* Rotate between K1 and K2 */
return SingleRotateWithRight( K1 );
}
/* START: fig4_37.txt */
AvlTree
Insert( ElementType X, AvlTree T )
{
if( T == NULL )
{
/* Create and return a one-node tree */
T = malloc( sizeof( struct AvlNode ) );
if( T == NULL )
FatalError( "Out of space!!!" );
else
{
T->Element = X;
T->Height = 0;
T->Left = T->Right = NULL;
}
}
else if( X < T->Element )
{
T->Left = Insert( X, T->Left );
if( Height( T->Left ) - Height( T->Right ) == 2 )
if( X < T->Left->Element )
T = SingleRotateWithLeft( T );
else
T = DoubleRotateWithLeft( T );
}
else if( X > T->Element )
{
T->Right = Insert( X, T->Right );
if( Height( T->Right ) - Height( T->Left ) == 2 )
if( X > T->Right->Element )
T = SingleRotateWithRight( T );
else
T = DoubleRotateWithRight( T );
}
/* Else X is in the tree already; we'll do nothing */
T->Height = Max( Height( T->Left ), Height( T->Right ) ) + 1;
return T;
}
/* 对单个结点进行AVL调整 */
static Position
Rotate4Delete( Position T )
{
if( Height(T->Left) - Height(T->Right) == 2 )
{
//比较T左孩子的左右子树高度来决定采取哪种旋转方式
if( Height(T->Left->Left) > Height(T->Left->Right) )
{
T = SingleRotateWithLeft( T );
}
else
{
T = DoubleRotateWithLeft( T ); /*LR*/
}
}
if( Height(T->Right) - Height(T->Left) == 2)
{
if( Height(T->Right->Right) > Height(T->Right->Left) )
{
T = SingleRotateWithRight( T ); //RR
}
else
{
T = DoubleRotateWithRight( T ); // RL
}
}
return T;
}
AvlTree
Delete( ElementType X, AvlTree T )
{
// printf( "Sorry; Delete is unimplemented; %d remains\n", X );
if( T == NULL )
return NULL;
if( X == T->Element )
{
//此节点左右儿子都不为空
if( T->Left != NULL & T->Right != NULL )
{
Position tmp = T->Right;
while( tmp->Left != NULL )
{
tmp = tmp->Left;
}
T->Element = tmp->Element;
T->Right = Delete( tmp->Element , T->Right);
T->Height = Max( Height( T->Left ), Height( T->Right ) ) + 1;
}
else //此节点有1个或0个子儿子
{
Position tmp = T;
T = ( T->Left != NULL ) ? T->Left : T->Right;
/*
if(T->Left == NULL){
T = T->Right;
}else if(t->Right == NULL){
T = T->Left;
}
*/
free( tmp );
tmp = NULL;
}
return T;
}
else if( X < T->Element )
{
T->Left = Delete( X, T->Left);
if(T->Left != NULL)
{
T->Left = Rotate4Delete( T->Left );
}
}
else
{
T->Right = Delete( X , T->Right);
if( T->Right != NULL )
{
T->Right = Rotate4Delete( T->Right );
}
}
T->Height = Max( Height( T->Left ), Height( T->Right ) ) + 1;
if( T != NULL )
{
T = Rotate4Delete( T );
}
return T;
}
ElementType
Retrieve( Position P )
{
if( NULL != P)
{
return P->Element;
}
else
{
return NULL;
}
}
void PreOrder(AvlTree T)
{
if(T != NULL)
{
printf("current element is %d, height is %d, left child is %d ,right child is %d \n", Retrieve(T), Height(T), Retrieve(T->Left), Retrieve(T->Right));
PreOrder(T->Left);
PreOrder(T->Right);
}
}
/*左子树和右子树高度差小于或者等于1*/
int isAvlTree( AvlTree T ){
if( T != NULL )
{
if( abs(Height(T->Left) - Height(T->Right)) < 2)
{
isAvlTree(T->Left);
isAvlTree(T->Right);
return 1;
}
return 0;
}
}
#include "fatal.h"
#include <stdlib.h>
#include <math.h>
typedef struct AvlNode *AvlTree;
typedef struct AvlNode *Position;
{
ElementType Element;
AvlTree Left;
AvlTree Right;
int Height;
};
AvlTree
MakeEmpty( AvlTree T )
{
if( T != NULL )
{
MakeEmpty( T->Left );
MakeEmpty( T->Right );
free( T );
}
return NULL;
}
Position
Find( ElementType X, AvlTree T )
{
if( T == NULL )
return NULL;
if( X < T->Element )
return Find( X, T->Left );
else if( X > T->Element )
return Find( X, T->Right );
else
return T;
}
Position
FindMin( AvlTree T )
{
if( T == NULL )
return NULL;
else if( T->Left == NULL )
return T;
else
return FindMin( T->Left );
}
Position
FindMax( AvlTree T )
{
if( T != NULL )
while( T->Right != NULL )
T = T->Right;
return T;
}
/* START: fig4_36.txt */
static int
Height( Position P )
{
if( P == NULL )
return -1;
else
return P->Height;
}
/* END */
static int
Max( int Lhs, int Rhs )
{
return Lhs > Rhs ? Lhs : Rhs;
}
/* START: fig4_39.txt */
/* This function can be called only if K2 has a left child */
/* Perform a rotate between a node (K2) and its left child */
/* Update heights, then return new root */
static Position
SingleRotateWithLeft( Position K2 ) // LL
{
//printf("SingleRotateWithLeft \n");
Position K1;
K1 = K2->Left;
K2->Left = K1->Right;
K1->Right = K2;
K2->Height = Max( Height( K2->Left ), Height( K2->Right ) ) + 1;
K1->Height = Max( Height( K1->Left ), K2->Height ) + 1;
return K1; /* New root */
}
/* END */
/* This function can be called only if K1 has a right child */
/* Perform a rotate between a node (K1) and its right child */
/* Update heights, then return new root */
static Position
SingleRotateWithRight( Position K1 ) //RR
{
//printf("SingleRotateWithRight \n");
Position K2;
K2 = K1->Right;
K1->Right = K2->Left;
K2->Left = K1;
K1->Height = Max( Height( K1->Left ), Height( K1->Right ) ) + 1;
K2->Height = Max( Height( K2->Right ), K1->Height ) + 1;
return K2; /* New root */
}
/* START: fig4_41.txt */
/* This function can be called only if K3 has a left */
/* child and K3's left child has a right child */
/* Do the left-right double rotation */
/* Update heights, then return new root */
static Position
DoubleRotateWithLeft( Position K3 ) // LR
{
/* Rotate between K1 and K2 */
K3->Left = SingleRotateWithRight( K3->Left );
/* Rotate between K3 and K2 */
return SingleRotateWithLeft( K3 );
}
/* END */
/* This function can be called only if K1 has a right */
/* child and K1's right child has a left child */
/* Do the right-left double rotation */
/* Update heights, then return new root */
static Position
DoubleRotateWithRight( Position K1 ) //RL
{
/* Rotate between K3 and K2 */
K1->Right = SingleRotateWithLeft( K1->Right );
/* Rotate between K1 and K2 */
return SingleRotateWithRight( K1 );
}
/* START: fig4_37.txt */
AvlTree
Insert( ElementType X, AvlTree T )
{
if( T == NULL )
{
/* Create and return a one-node tree */
T = malloc( sizeof( struct AvlNode ) );
if( T == NULL )
FatalError( "Out of space!!!" );
else
{
T->Element = X;
T->Height = 0;
T->Left = T->Right = NULL;
}
}
else if( X < T->Element )
{
T->Left = Insert( X, T->Left );
if( Height( T->Left ) - Height( T->Right ) == 2 )
if( X < T->Left->Element )
T = SingleRotateWithLeft( T );
else
T = DoubleRotateWithLeft( T );
}
else if( X > T->Element )
{
T->Right = Insert( X, T->Right );
if( Height( T->Right ) - Height( T->Left ) == 2 )
if( X > T->Right->Element )
T = SingleRotateWithRight( T );
else
T = DoubleRotateWithRight( T );
}
/* Else X is in the tree already; we'll do nothing */
T->Height = Max( Height( T->Left ), Height( T->Right ) ) + 1;
return T;
}
/* 对单个结点进行AVL调整 */
static Position
Rotate4Delete( Position T )
{
if( Height(T->Left) - Height(T->Right) == 2 )
{
//比较T左孩子的左右子树高度来决定采取哪种旋转方式
if( Height(T->Left->Left) > Height(T->Left->Right) )
{
T = SingleRotateWithLeft( T );
}
else
{
T = DoubleRotateWithLeft( T ); /*LR*/
}
}
if( Height(T->Right) - Height(T->Left) == 2)
{
if( Height(T->Right->Right) > Height(T->Right->Left) )
{
T = SingleRotateWithRight( T ); //RR
}
else
{
T = DoubleRotateWithRight( T ); // RL
}
}
return T;
}
AvlTree
Delete( ElementType X, AvlTree T )
{
// printf( "Sorry; Delete is unimplemented; %d remains\n", X );
if( T == NULL )
return NULL;
if( X == T->Element )
{
//此节点左右儿子都不为空
if( T->Left != NULL & T->Right != NULL )
{
Position tmp = T->Right;
while( tmp->Left != NULL )
{
tmp = tmp->Left;
}
T->Element = tmp->Element;
T->Right = Delete( tmp->Element , T->Right);
T->Height = Max( Height( T->Left ), Height( T->Right ) ) + 1;
}
else //此节点有1个或0个子儿子
{
Position tmp = T;
T = ( T->Left != NULL ) ? T->Left : T->Right;
/*
if(T->Left == NULL){
T = T->Right;
}else if(t->Right == NULL){
T = T->Left;
}
*/
free( tmp );
tmp = NULL;
}
return T;
}
else if( X < T->Element )
{
T->Left = Delete( X, T->Left);
if(T->Left != NULL)
{
T->Left = Rotate4Delete( T->Left );
}
}
else
{
T->Right = Delete( X , T->Right);
if( T->Right != NULL )
{
T->Right = Rotate4Delete( T->Right );
}
}
T->Height = Max( Height( T->Left ), Height( T->Right ) ) + 1;
if( T != NULL )
{
T = Rotate4Delete( T );
}
return T;
}
ElementType
Retrieve( Position P )
{
if( NULL != P)
{
return P->Element;
}
else
{
return NULL;
}
}
void PreOrder(AvlTree T)
{
if(T != NULL)
{
printf("current element is %d, height is %d, left child is %d ,right child is %d \n", Retrieve(T), Height(T), Retrieve(T->Left), Retrieve(T->Right));
PreOrder(T->Left);
PreOrder(T->Right);
}
}
/*左子树和右子树高度差小于或者等于1*/
int isAvlTree( AvlTree T ){
if( T != NULL )
{
if( abs(Height(T->Left) - Height(T->Right)) < 2)
{
isAvlTree(T->Left);
isAvlTree(T->Right);
return 1;
}
return 0;
}
}