AVL树C/C++代码实现

15 篇文章 0 订阅
12 篇文章 0 订阅
avltrre.h
    #include "avlnode.h"  
      
    template <class T>  
    class AvlTree{  
      
        AvlNode<T> *root;  
      
        bool Insert(AvlNode<T> *& rt,T x, bool &taller);  
        bool Remove(AvlNode<T> *& rt,T x, bool &shorter);  
      
        void RotateLeft(AvlNode<T> * &node);  //左旋函数  
        void RotateRight(AvlNode<T> * &node); //右旋函数  
      
        void RightBalanceAfterInsert(AvlNode<T> * &sRoot, bool &taller);  
        void LeftBalanceAfterInsert(AvlNode<T> * &sRoot, bool &taller);  
        void RightBalanceAfterDelete(AvlNode<T> * &sRoot, bool &shorter);  
        void LeftBalanceAfterDelete(AvlNode<T> * &sRoot, bool &shorter);  
      
    public:  
             
        AvlTree():root(NULL){}  
        AvlNode<T>* getRoot() const  
        {  
            return root;  
        }  
      
        bool Insert(T x)  
        {  
            bool taller = false;  
            return Insert(root, x, taller );  
        }  
      
        bool Remove(T x)  
        {  
            bool shorter = false;  
            return Remove(root, x, shorter);  
        }  
          
        //输出树形结构  
        void DisplayTree(AvlNode<T> *t,int layer) const;  
    };  
      
    template <typename T>  
    void AvlTree<T>::RotateLeft(AvlNode<T> * & node)  
    {  
         if( (node == NULL) || (node->rightChild == NULL) ) return;  
           
         AvlNode<T> * tmpNode = new AvlNode<T>(node->data);  
         if(tmpNode == NULL ) return;  
           
         tmpNode->leftChild = node->leftChild;  
         node->leftChild = tmpNode;  
         tmpNode->rightChild = node->rightChild->leftChild;  
      
         AvlNode<T> *toDelete = node->rightChild;  
         node->data = toDelete->data;       
         node->rightChild = toDelete->rightChild;  
           
         delete toDelete;  
    }  
      
    template <typename T>  
    void AvlTree<T>::RotateRight(AvlNode<T> * & node)  
    {  
         if( (node == NULL) || (node->leftChild == NULL) ) return;  
           
         AvlNode<T> *tmpNode = new AvlNode<T>(node->data);  
         if(tmpNode == NULL ) return;  
           
         tmpNode->rightChild = node->rightChild;  
         node->rightChild = tmpNode;  
         tmpNode->leftChild = node->leftChild->rightChild;  
      
         AvlNode<T> *toDelete = node->leftChild;  
         node->data = toDelete->data;  
         node->leftChild = toDelete->leftChild;  
           
         delete toDelete;  
    }  
      
    //如果插入节点后, rt的右高度增加, 则调用此函数进行平衡化  
    template <typename T>  
    void AvlTree<T>::RightBalanceAfterInsert(AvlNode<T> *&sRoot,bool &taller)  
    {  
        if( (sRoot == NULL) || (sRoot->rightChild == NULL) ) return;  
        AvlNode<T> *rightsub = sRoot->rightChild,*leftsub;  
        switch(rightsub->balance){  
            case 1:  
                sRoot->balance = rightsub->balance = 0;  
                RotateLeft(sRoot);  
                taller = false; break;  
            case 0:  
                cout<<"树已经平衡化."<<endl; break;  
            case -1:  
                leftsub = rightsub->leftChild;  
                switch(leftsub->balance){  
                    case 1:  
                        sRoot->balance = -1; rightsub->balance = 0; break;  
                    case 0:  
                        sRoot->balance = rightsub->balance = 0; break;  
                    case -1:  
                        sRoot->balance = 0; rightsub->balance = 1; break;  
                }  
                leftsub->balance = 0;  
                RotateRight(rightsub);  
                RotateLeft(sRoot);  
                taller = false; break;  
        }  
    }  
      
    //如果插入节点后, rt的左高度增加, 则调用此函数进行平衡化  
    template <typename T>  
    void AvlTree<T>::LeftBalanceAfterInsert(AvlNode<T> *&sRoot,bool &taller)  
    {  
        AvlNode<T> *leftsub = sRoot->leftChild,*rightsub;  
        switch(leftsub->balance){  
            case -1:  
                sRoot->balance = leftsub->balance = 0;  
                RotateRight(sRoot);  
                taller = false; break;  
            case 0:  
                cout<<"树已经平衡化."<<endl; break;  
            case 1:  
                rightsub = leftsub->rightChild;  
                switch(rightsub->balance){  
                    case -1:  
                        sRoot->balance = 1; leftsub->balance = 0; break;  
                    case 0:  
                        sRoot->balance = leftsub->balance = 0; break;  
                    case 1:  
                        sRoot->balance = 0; leftsub->balance = -1; break;  
                }  
                rightsub->balance = 0;  
                RotateLeft(leftsub);  
                RotateRight(sRoot);  
                taller = false; break;  
        }  
    }  
      
    //如果删除节点后, rt的左高度减少, 则调用此函数进行平衡化  
    template <typename T>  
    void AvlTree<T>::RightBalanceAfterDelete(AvlNode<T> * &sRoot,bool &shorter)  
    {  
        AvlNode<T> *rightsub = sRoot->rightChild,*leftsub;  
        switch(rightsub->balance){  
            case 1: sRoot->balance = sRoot->balance = 0; RotateLeft(sRoot); break;  
            case 0: sRoot->balance = 0; rightsub->balance = -1; RotateLeft(sRoot); break;  
            case -1:  
                leftsub = rightsub->leftChild;  
                switch(leftsub->balance){  
                    case -1: sRoot->balance = 0; rightsub->balance = 1; break;  
                    case 0: sRoot->balance = rightsub->balance = 0; break;  
                    case 1: sRoot->balance = -1; rightsub->balance = 0; break;  
                }  
                leftsub->balance = 0;  
                RotateRight(rightsub);  
                RotateLeft(sRoot);  
                shorter = false; break;  
        }  
    }  
      
    //如果删除节结点后, rt的右高度减少, 则调用此函数进行平衡化  
    template <typename T>  
    void AvlTree<T>::LeftBalanceAfterDelete(AvlNode<T> * &sRoot,bool &shorter)  
    {  
        AvlNode<T> *leftsub = sRoot->leftChild,*rightsub;  
        switch(leftsub->balance){  
            case 1: sRoot->balance = sRoot->balance = 0; RotateRight(sRoot); break;  
            case 0: sRoot->balance = 0; leftsub->balance = -1; RotateRight(sRoot); break;  
            case -1:  
                rightsub = leftsub->rightChild;  
                switch(rightsub->balance){  
                    case -1: sRoot->balance = 0; leftsub->balance = 1; break;  
                    case 0: sRoot->balance = leftsub->balance = 0; break;  
                    case 1: sRoot->balance = -1; leftsub->balance = 0; break;  
                }  
                rightsub->balance = 0;  
                RotateLeft(leftsub);  
                RotateRight(sRoot);  
                shorter = false; break;  
        }  
    }  
      
    //插入值为x的结点, 实现方式采用递归  
    template <typename T>  
    bool AvlTree<T>::Insert(AvlNode<T> *& rt, T x, bool &taller)  
    {   
        bool success;  
      
        //递归函数的"基本条件"  
        if ( rt == NULL )  
        {   
           rt = new AvlNode<T>(x);  
           success = rt != NULL ? true : false;  
           if ( success ) taller = true;  
        }  
        //如果x的值小于rt的关键码  
        else if ( x < rt->data )  
        {  
           //Insert的递归调用,从rt的左子树寻找合适的位置插入   
           success = Insert ( rt->leftChild, x, taller );  
      
           if ( taller ){//如果插入后使得rt的左高度增加   
                 switch ( rt->balance ) {  
                    case -1 : LeftBalanceAfterInsert( rt, taller ); break;  
                    case 0 :  rt->balance = -1; break;  
                    case 1 :  rt->balance = 0;  taller = false; break;    
                }        
            }  
        }  
        //如果x的值大于rt的关键码  
        else if ( x > rt->data )  
        {  
           //Insert的递归调用,从rt的右子树寻找合适的位置插入   
           success = Insert ( rt->rightChild, x, taller );  
             
           if ( taller ){//如果插入后使得rt的右高度增加   
              switch ( rt->balance ) {                
                case -1:   
                    rt->balance = 0;   
                    taller = false;   
                    break;  
                case 0 :   
                    rt->balance = 1;   
                    break;    
                case 1 :   
                    RightBalanceAfterInsert(rt, taller);   
                    break;  
            }  
         }  
        }  
        return success;      
    }  
      
    //删除值为x的结点, 实现方式采用递归   
    template <typename T>  
    bool AvlTree<T>::Remove(AvlNode<T> *& rt, T x, bool &shorter)  
    {  
        bool success = false;  
        if(rt == NULL) return false;  
      
        //如果rt就是要删除的结点  
        if(x == rt->data) {   
            if(rt->leftChild != NULL && rt->rightChild != NULL)   
            {  
              
                //寻找rt的中序遍历的前驱结点,用r表示   
                AvlNode<T> *r = rt->leftChild;  
                while(r->rightChild != NULL) {  
                     r = r->rightChild;  
                }  
                  
                //交换rt和r的值   
                T temp = rt->data;  
                rt->data = r->data;  
                r->data = temp;  
                  
                //递归函数, 从rt的左子树中删除关键码为x的结点  
                success = Remove(rt->leftChild, x, shorter);  
                if(shorter) {//如果删除后引起rt的左高度减少  
                    switch(rt->balance) {  
                        case -1: rt->balance = 0; break;  
                        case 0 : rt->balance = 1; shorter = 0; break;  
                        case 1 : RightBalanceAfterDelete(rt, shorter);break;  
                    }  
                }  
            }  
            else {//rt最多只有一个子女,这是递归的出口   
                 AvlNode<T> *p = rt;  
                 rt = rt->leftChild != NULL ? rt->leftChild : rt->rightChild;  
                 delete p;  
                 success = true;  
                 shorter = true;  
            }  
        }  
      
        else if(x < rt->data) {  
            //递归函数调用,从rt的左子树中删除关键码为x的结点  
            success = Remove(rt->leftChild, x, shorter);  
            if(shorter) {//如果删除后引起rt的左高度减少  
                switch(rt->balance) {  
                    case -1: rt->balance = 0; break;  
                    case 0 : rt->balance = 1; shorter = 0; break;  
                    case 1 : RightBalanceAfterDelete(rt, shorter); break;  
                }  
            }  
        }  
      
        else if(x > rt->data) {  
            //递归函数调用,从rt的右子树中删除关键码为x的结点  
            success = Remove(rt->rightChild, x, shorter);  
            if(shorter) {//如果删除后引起sRoot的右高度减少  
                switch(rt->balance) {  
                    case -1: LeftBalanceAfterDelete(rt, shorter); break;  
                    case 0 : rt->balance = -1; shorter = 0; break;  
                    case 1 : rt->balance = 0; break;  
                }  
            }  
        }  
        return success;  
    }  
      
    template <typename T>  
    void AvlTree<T>::DisplayTree(AvlNode<T> *t,int layer) const  
    {  
        if(t == NULL)  
            return;  
        if(t->rightChild)  
            DisplayTree(t->rightChild, layer+1);  
        for(int i =0;i<layer;i++)  
            cout<<"    ";  
        cout<<t->data<<endl;  
        if(t->leftChild)  
            DisplayTree(t->leftChild,layer+1);  
    }  
avlnode.h
    #ifndef AVLNODE_H  
    #define AVLNODE_H  
      
    #include <iostream>  
      
    using namespace std;  
      
    template <class T> class AvlTree; //声明AvlTree类  
      
    template <class T>  
    class AvlNode{  
      
        T data;                 //关键码  
        AvlNode *leftChild;     //左孩子  
        AvlNode *rightChild;    //右孩子  
        int balance;            //平衡因子  
      
    public:  
      
        //构造函数  
        AvlNode():left(NULL),right(NULL),balance(0){};  
      
        AvlNode(const T& e,AvlNode<T> *lt = NULL,AvlNode<T> *rt = NULL)  
            :data(e),leftChild(lt),rightChild(rt),balance(0){};  
      
        int getBalance() const  
        {  
            return balance;  
        }  
        AvlNode<T>* getLeftChild() const  
        {  
            return leftChild;  
        }  
        AvlNode<T>* getRightChild() const  
        {  
            return rightChild;  
        }  
        T getData() const  
        {  
            return data;  
        }  
      
        friend class AvlTree<T>;  
    };  
    #endif  

main.cpp代码可以自己完成,需对stl有了解,能够运用,写算法能够对C++的锻炼。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值