平衡树AVL

#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;
}

 

posted @ 2015-05-05 10:14  crazyzhping  阅读(107)  评论(0)    收藏  举报