您的位置:首页 > 其它

AVL Tree 的实现

2016-06-28 14:54 239 查看
http://blog.csdn.net/zk_sima/article/details/6268127

首先 AVL 树是平衡二叉搜索树,所以首先 必须满足搜索树,即l_child值<parent值<=r_child值。这个在前面已经实现了。插入和删除不停的递归就可以。

其次 AVL 树是平衡二叉树,他的平衡条件是左右子树的深度之差小于2.而关键问题在怎么计算深度之差。

一般的方法都是通过平衡度来衡量的。而平衡度怎么得到呢,一般是通过左右子树的深度差得到。其实别人怎么得到平衡度我也没搞明白,不过在这里我是参考了一中思路,就是在每个节点中 包含它自己的高度,而没有直接包含平衡度。

节点的结构:

[cpp] view
plain copy

template<typename T>  

struct node  

{  

    typedef typename node*  PVOID;  

    PVOID                   l_child;//指向左子树  

    PVOID                   r_child;//右子树指针  

    T                       value;//节点值  

private:  

    int                     height;//节点高度  

public:  

    int getHeight()//得到该节点的高度  

    {  

        if(NULL==this)  

            return 0;  

        else  

            return this->height;  

    }  

    void setHeight()//设置节点的高度  

    {  

        if(NULL==this)  

            return ;  

        int lh,rh;  

        lh=this->l_child->getHeight();  

        rh=this->r_child->getHeight();  

        this->height=lh>rh?(lh+1):(rh+1);  

        return ;  

    }  

    bool ifBalance()//判断该节点是否破坏平衡条件  

    {  

        int flag=this->l_child->getHeight()-this->r_child->getHeight();  

        return flag<2&&flag>-2;  

    }  

    node(T key):l_child(0),r_child(0),value(key),height(1){}  

};  

 

其实AVL 的算法很简单,AVL算法的示意图和神马的前人都给你画出来了,而实现这些算法,主要就在内存分配上,和指针的处理上。

而这里面 最主要的就是 高度的处理上面。

AVL的基本算法:

[cpp] view
plain copy

void ll_rotation(PNODE& pNode)//左左  

    {  

        PNODE tempNode=pNode->l_child->r_child;  

        pNode->l_child->r_child=pNode;  

        pNode=pNode->l_child;  

        pNode->r_child->l_child=tempNode;  

        pNode->r_child->setHeight();  

        pNode->setHeight();  

    }     

    void lr_rotation(PNODE& pNode)//左右  

    {  

        PNODE tempNode=pNode->l_child->r_child->l_child;  

        pNode->l_child->r_child->l_child=pNode->l_child;  

        pNode->l_child=pNode->l_child->r_child;  

        pNode->l_child->l_child->r_child=tempNode;  

        pNode->l_child->l_child->setHeight();  

        pNode->l_child->setHeight();  

        ll_rotation(pNode);  

    }  

    void rl_rotation(PNODE& pNode)//右左  

    {  

        PNODE tempNode=pNode->r_child->l_child->r_child;  

        pNode->r_child->l_child->r_child=pNode->r_child;  

        pNode->r_child=pNode->r_child->l_child;  

        pNode->r_child->r_child->l_child=tempNode;  

        pNode->r_child->r_child->setHeight();  

        pNode->r_child->setHeight();  

        rr_rotation(pNode);  

    }  

    void rr_rotation(PNODE& pNode)//右右  

    {  

        PNODE tempNode=pNode->r_child->l_child;  

        pNode->r_child->l_child=pNode;  

        pNode=pNode->r_child;  

        pNode->l_child->r_child=tempNode;  

        pNode->l_child->setHeight();  

        pNode->setHeight();  

    }  

 

怎么让AVL树恢复平衡:

[cpp] view
plain copy

void rebalance(PNODE& pNode)//恢复树的平衡  

    {  

        if(pNode->l_child->getHeight()>pNode->r_child->getHeight())  

        {  

            if(pNode->l_child->l_child->getHeight()>pNode->l_child->r_child->getHeight())  

                return ll_rotation(pNode);  

            else  

                return lr_rotation(pNode);  

        }  

        else  

        {  

            if(pNode->r_child->l_child->getHeight()>pNode->r_child->r_child->getHeight())  

                return rl_rotation(pNode);  

            else  

                return rr_rotation(pNode);  

        }  

    }  

 

具体代码:

[cpp] view
plain copy

template<typename T>  

struct node  

{  

    typedef typename node*  PVOID;  

    PVOID                   l_child;//指向左子树  

    PVOID                   r_child;//右子树指针  

    T                       value;//节点值  

private:  

    int                     height;//节点高度  

public:  

    int getHeight()//得到该节点的高度  

    {  

        if(NULL==this)  

            return 0;  

        else  

            return this->height;  

    }  

    void setHeight()//设置节点的高度  

    {  

        if(NULL==this)  

            return ;  

        int lh,rh;  

        lh=this->l_child->getHeight();  

        rh=this->r_child->getHeight();  

        this->height=lh>rh?(lh+1):(rh+1);  

        return ;  

    }  

    bool ifBalance()//判断该节点是否破坏平衡条件  

    {  

        int flag=this->l_child->getHeight()-this->r_child->getHeight();  

        return flag<2&&flag>-2;  

    }  

    node(T key):l_child(0),r_child(0),value(key),height(1){}  

};  

template<class T>  

class AVLTree  

{  

public:  

    typedef typename node<T>*   PNODE;  

private:  

    PNODE root;//跟节点,对于一颗搜索二叉树来说只需要保存跟节点 就可以遍历整棵树  

private://这些函数负责 内存管理  

    PNODE createNode(T  value)//分配内存 ,并构造  

    {  

        PNODE pNode=(PNODE)malloc(sizeof(node<T>));//首先分配内存  

        new(pNode) node<T>(value);//对这段内存进行构造  

        return pNode;  

    }  

    void deallocNode(PNODE& pNode)//释放空间  

    {  

        free(pNode);  

        pNode=0;  

    }  

private:  

    void ll_rotation(PNODE& pNode)//左左  

    {  

        PNODE tempNode=pNode->l_child->r_child;  

        pNode->l_child->r_child=pNode;  

        pNode=pNode->l_child;  

        pNode->r_child->l_child=tempNode;  

        pNode->r_child->setHeight();  

        pNode->setHeight();  

    }     

    void lr_rotation(PNODE& pNode)//左右  

    {  

        PNODE tempNode=pNode->l_child->r_child->l_child;  

        pNode->l_child->r_child->l_child=pNode->l_child;  

        pNode->l_child=pNode->l_child->r_child;  

        pNode->l_child->l_child->r_child=tempNode;  

        pNode->l_child->l_child->setHeight();  

        pNode->l_child->setHeight();  

        ll_rotation(pNode);  

    }  

    void rl_rotation(PNODE& pNode)//右左  

    {  

        PNODE tempNode=pNode->r_child->l_child->r_child;  

        pNode->r_child->l_child->r_child=pNode->r_child;  

        pNode->r_child=pNode->r_child->l_child;  

        pNode->r_child->r_child->l_child=tempNode;  

        pNode->r_child->r_child->setHeight();  

        pNode->r_child->setHeight();  

        rr_rotation(pNode);  

    }  

    void rr_rotation(PNODE& pNode)//右右  

    {  

        PNODE tempNode=pNode->r_child->l_child;  

        pNode->r_child->l_child=pNode;  

        pNode=pNode->r_child;  

        pNode->l_child->r_child=tempNode;  

        pNode->l_child->setHeight();  

        pNode->setHeight();  

    }  

    void rebalance(PNODE& pNode)//恢复树的平衡  

    {  

        if(pNode->l_child->getHeight()>pNode->r_child->getHeight())  

        {  

            if(pNode->l_child->l_child->getHeight()>pNode->l_child->r_child->getHeight())  

                return ll_rotation(pNode);  

            else  

                return lr_rotation(pNode);  

        }  

        else  

        {  

            if(pNode->r_child->l_child->getHeight()>pNode->r_child->r_child->getHeight())  

                return rl_rotation(pNode);  

            else  

                return rr_rotation(pNode);  

        }  

    }  

    void insert(PNODE &pParent,PNODE pNode)//插入节点  

    {  

        if(0==pParent)  

        {  

            pParent=pNode;  

            return ;  

        }  

        if(pNode->value>=pParent->value)  

            insert(pParent->r_child,pNode);  

        else if(pNode->value <pParent->value)  

            insert(pParent->l_child,pNode);  

        pParent->setHeight();  

        if(pParent->ifBalance())  

            return ;  

        else  

            rebalance(pParent);  

    }  

    void remove(PNODE& pParent,T value)//删除某个节点  

    {  

        if(0==pParent)  

            return ;  

        if(value>pParent->value)  

            remove(pParent->r_child,value);  

        else if(value<pParent->value)  

            remove(pParent->l_child,value);  

        else  

        {  

            if(0!=pParent->l_child&&0!=pParent->r_child)  

            {  

                PNODE p=pParent->r_child;  

                while(p->l_child)  

                    p=p->l_child;  

                pParent->value=p->value;  

                p->value=value;  

                remove(pParent->r_child,value);  

            }  

            else   

            {  

                if(0!=pParent->l_child&&0==pParent->r_child)  

                {  

                    PNODE tempNode=pParent;  

                    pParent=pParent->l_child;  

                    return this->deallocNode(tempNode);  

                }  

                else   

                {  

                    if(0!=pParent->r_child&&0==pParent->l_child)  

                    {  

                        PNODE tempNode=pParent;  

                        pParent=pParent->r_child;  

                        return this->deallocNode(tempNode);  

                    }  

                    else if(0==pParent->r_child&&0==pParent->l_child)  

                        return this->deallocNode(pParent);  

                }  

            }  

        }  

        pParent->setHeight();  

        if(pParent->ifBalance())  

            return ;  

        return rebalance(pParent);  

    }  

public:  

    AVLTree():root(0){}//构造函数  

    void insert(T value)//插入值  

    {  

        PNODE pNode=this->createNode(value);  

        insert(root,pNode);  

    }  

    void remove(T value)//删除值  

    {  

        remove(root,value);  

    }  

    T getMax()//得到最大值  

    {  

        if(0==root)  

            return T(0);  

        T max=root->value;  

        PNODE p=root;  

        while(p)  

        {  

            max=p->value;  

            p=p->r_child;  

        }  

        return max;  

    }  

    T getMin()//得到最小值  

    {  

        if(0==root)  

            return T(0);  

        T min=root->value;  

        PNODE p=root;  

        while(p)  

        {  

            min=p->value;  

            p=p->l_child;  

        }  

        return min;  

    }  

};  

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  AVL