#include<iostream>
#include<stack>
using namespace std;
class AVL
{
public:
enum BF { RH = 1 , EH , LH };
class Node
{
public:
Node* lchild;
Node* rchild;
int data;
BF bf;
Node(): lchild(NULL) , rchild(NULL) , data(0) , bf(EH) {}
};
typedef Node* PNode;
PNode root;
public:
AVL():root(NULL) {}
~AVL(){ DestoryTree(); }
int Insert(int value );
int InsertAVL( PNode& T , int value , int &taller );
int InsertAVL( int value);
int Delete( int value);
void R_Rotate( PNode &T );
void L_Rotate( PNode &T );
void LeftBalance( PNode &T);
void RightBalance( PNode &T);
void print();
void DFS(PNode &T);
void DestoryTree();
void Destory( PNode &T );
};
int AVL::InsertAVL( int value)
{
if( !root )
{
root = new Node;
root->data = value;
return true;
}
else
{
PNode p = root ;
PNode q = NULL;
stack<PNode> s;
while( p && p->data != value )
{
q = p;
s.push(p);
if( value < p->data )
{
p = p->lchild;
}
else
p = p->rchild;
}
if( p && p->data == value )
return false;
else
{
PNode temp = new Node;
temp->data = value;
if( value < q->data )
q->lchild = temp;
else
q->rchild = temp;
q = temp;
while( !s.empty() )
{
PNode t = s.top();
PNode tt;
s.pop();
if( !s.empty() )
tt = s.top();
if( t->lchild == q )
{
int isok = true;
switch( t->bf )
{
case LH:
if( !s.empty() )
{
if( tt->lchild == t )
LeftBalance( tt->lchild );
else if ( tt->rchild == t )
LeftBalance( tt->rchild );
isok = false;
}else
{
LeftBalance( root );
isok = false;
}
break;
case EH:
t->bf = LH;
break;
case RH:
t->bf = EH;
break;
}
if( !isok )
break;
}
else if( t->rchild == q )
{
int isok = true;
switch( t->bf )
{
case LH:
t->bf = EH;
break;
case EH:
t->bf = RH;
break;
case RH:
if( !s.empty() )
{
if( tt->lchild == t )
RightBalance( tt->lchild );
else
RightBalance( tt->rchild );
isok = false;
}
else
RightBalance( root );
break;
}
if( !isok )
break;
}
q = t;
}
}
return true;
}
}
int AVL::Insert( int value)
{
int taller;
// int res = InsertAVL( root , value , taller ); // 递归写法
int res = InsertAVL( value ); // 非递归写法
cout << "============Insert " << value << "============" << endl;
print();
cout << endl;
return res;
}
void AVL::R_Rotate( PNode &T )
{
PNode lc = T->lchild;
T->lchild = lc->rchild ;
lc->rchild = T;
T = lc;
}
void AVL::L_Rotate( PNode& T )
{
PNode rc = T->rchild ;
T->rchild = rc->lchild;
rc->lchild = T ;
T = rc;
}
void AVL::LeftBalance( PNode& T )
{
PNode &temp = T->lchild ;
switch( temp->bf )
{
case LH:
T->bf = EH;
temp->bf = EH;
R_Rotate( T );
break;
case RH:
PNode temp2 = temp->rchild;
switch( temp2->bf )
{
case LH:
temp2->bf = EH;
T->bf = RH;
temp->bf = EH;
break;
case EH:
temp2->bf = T->bf = temp->bf = EH;
break;
case RH:
T->bf = EH;
temp->bf = LH;
temp2->bf = EH;
break;
}
L_Rotate( temp );
R_Rotate( T );
break;
}
}
void AVL::RightBalance( PNode& T )
{
PNode &temp = T->rchild ;
switch( temp->bf )
{
case RH:
T->bf = temp->bf = EH;
L_Rotate( T );
break;
case LH:
PNode temp2 = temp->lchild;
switch( temp2->bf )
{
case LH:
T->bf = EH;
temp2->bf = EH;
temp->bf = RH;
break;
case RH:
T->bf = LH;
temp2->bf = EH;
temp->bf = EH;
break;
case EH:
T->bf = temp2->bf = temp->bf = EH;
break;
}
R_Rotate( temp );
L_Rotate( T );
break;
}
}
int AVL::InsertAVL( PNode& T , int value , int& taller )
{
if( !T )
{
PNode temp = new Node;
temp->data = value;
temp->bf = EH;
T = temp;
taller = true;
}
else
{
if( T->data == value )
{
taller = false;
return false;
}
else if( T->data > value )
{
if( InsertAVL( T->lchild , value , taller ) )
{
if( taller )
{
switch( T->bf )
{
case LH:
LeftBalance( T );
taller = false;
break;
case EH:
T->bf = LH;
taller = true;
break;
case RH:
T->bf = EH;
taller = false;
break;
}
}
}
else
return false;
}
else
{
if( InsertAVL( T->rchild , value , taller ) )
{
if ( taller )
{
switch( T->bf )
{
case LH:
T->bf = EH;
taller = false;
break;
case EH:
T->bf = RH;
taller = true;
break;
case RH:
RightBalance(T);
taller = false;
break;
}
}
}
else
return false;
}
}
return true;
}
void AVL::DFS(PNode &T)
{
if( T )
{
if( T->lchild )
DFS( T->lchild );
cout << "visit " << T->data << " The bf is " << T->bf - 2 << endl;
if( T->rchild )
DFS( T->rchild );
}
}
void AVL::print()
{
DFS( root );
}
void AVL::DestoryTree()
{
Destory( root );
}
void AVL::Destory( PNode& T )
{
if( T )
{
PNode q = T ;
if( T->lchild )
Destory( T->lchild );
if( T->rchild )
Destory( T->rchild );
free( q );
T = NULL;
}
}
int main()
{
AVL avl;
avl.Insert( 10 );
// avl.Insert( 12 );
avl.Insert( 2 );
avl.Insert( -1 );
avl.Insert( -2 );
avl.Insert( 8 );
avl.Insert( 5 );
return 0;
}