AVL Tree(上)

1:定义

AVL树又称平衡二叉搜索树,它的任意一个节点的左右子树的高度差不超过1,这样能减少数的高度,以达到减少搜索次数的目的。

2:AVL节点的结构

    //Key Value结构的AVL树
    K _key;
    AVLTreeNode<K, V>* _Left;
    AVLTreeNode<K, V>* _Right;
    AVLTreeNode<K, V>* _parent;
    V _value;
    int _bf;             //平衡因子(右子树高度-左子树高度)

3:AVL节点的插入

当我们插入一个节点时,会从当前插入的这个节点向上进行检查,检查到的节点的平衡因子如果等于0;则可以说明这个节点上面的平衡因子在插入新的节点之前已经更新过了,不用再进行调整,如果平衡因子等于-1或者 1,则需要继续向上查找,直到遍历到这颗树的根节点或者遍历到有节点的平衡因子为2或-2为止。

while (parent)
        {
            //
            if (parent->_Left ==cur)
                parent->_bf--;
            else
                parent->_bf++;


            if (parent->_bf == 0)
                break;
            else if (abs(parent->_bf) == 1)
            {
                cur = parent;
                parent = parent->_parent;
            }
            else
            {
                /*_UpdataBalanceFactor(parent);*/
                if ((parent->_bf == -2) && (parent->_Left->_bf == -1))
                {
                    //进行右单旋
                    _RotateR(parent);
                }

                else if ((parent->_bf == 2) && (parent->_Right->_bf) == 1)
                {
                    //进行左单旋
                    _RotateL(parent);
                }

                else if ((parent->_bf == 2) && (parent->_Right->_bf == -1))
                {
                    //进行右左双旋
                    _RotateRL(parent);
                }

                else
                {
                    //进行左右双旋
                    _RotateLR(parent);
                }
                break;
            }

1:右单旋

某节点的平衡因子为-2,其左孩子节点平衡因子为-1

2:左单旋

某节点的平衡因子为2,其右孩子节点的平衡因子为1

3:左右双旋

某节点的平衡因子为-2,其左孩子平衡因子为1
某节点的平衡因子为-2,其左孩子平衡因子为1

4:右左双旋

某节点的平衡因子为2,其右孩子节点的平衡因子为-1
某节点的平衡因子为2,其右孩子节点的平衡因子为-1

代码

#pragma once

#include <iostream>
using namespace std;
#include <cassert>
#include <string>


template <class K,class V>
struct AVLTreeNode
{
    K _key;
    AVLTreeNode<K, V>* _Left;
    AVLTreeNode<K, V>* _Right;
    AVLTreeNode<K, V>* _parent;
    V _value;
    int _bf;             //平衡因子(右子树高度-左子树高度)

    AVLTreeNode(const K& key, const V& value)
        :_key(key)
        , _Left(NULL)
        , _Right(NULL)
        , _parent(NULL)
        , _value(value)
        , _bf(0)
    {}
};


template<class K,class V>
class AVLTree
{
    typedef AVLTreeNode<K, V>  Node;

public:
    AVLTree()
        :_root(NULL)
    {}

    bool Insert(const K& key, const V& value)
    {
        if (_root == NULL)
        {
            _root = new Node(key, value);
            return true;
        }

        Node* cur = _root;
        Node* parent = NULL;
        //找到所要插入的位置
        while (cur)
        {
            if (cur->_key > key)
            {
                parent = cur;
                cur = cur->_Left;
            }
            else if (cur->_key < key)
            {
                parent = cur;
                cur = cur->_Right;
            }
            else
                return false;
        }

        cur = new Node(key, value);
        if (parent->_key < key)
        {
            parent->_Right = cur;
            cur->_parent = parent;
        }
        else
        {
            parent->_Left = cur;
            cur->_parent = parent;

        }

        while (parent)
        {
            //
            if (parent->_Left ==cur)
                parent->_bf--;
            else
                parent->_bf++;


            if (parent->_bf == 0)
                break;
            else if (abs(parent->_bf) == 1)
            {
                cur = parent;
                parent = parent->_parent;
            }
            else
            {
                /*_UpdataBalanceFactor(parent);*/
                if ((parent->_bf == -2) && (parent->_Left->_bf == -1))
                {
                    //进行右单旋
                    _RotateR(parent);
                }

                else if ((parent->_bf == 2) && (parent->_Right->_bf) == 1)
                {
                    //进行左单旋
                    _RotateL(parent);
                }

                else if ((parent->_bf == 2) && (parent->_Right->_bf == -1))
                {
                    //进行右左双旋
                    _RotateRL(parent);
                }

                else
                {
                    //进行左右双旋
                    _RotateLR(parent);
                }
                break;
            }
        }
            return true;
    }

        void Inorder()
        {
            _Inorder(_root);
            cout << endl;
        }

        //判断是否平衡
        bool IsBalance()
        {
            return _IsBalance(_root);
        }

        size_t GetHeight()
        {
            return _Height(_root);
        }

        bool IsBalanceOp()
        {
            int Height = 0;
            bool ret= _IsBalanceOp(_root,Height);
            cout << "Tree's height is:" << Height << endl;
            return ret;
        }
protected:
    bool _IsBalanceOp(Node* root,int& Height)
    {  
        if (root == NULL)
        {
            Height = 0;
            return true;
        }

        int RHeight = 0;
        int LHeight = 0;

        if (_IsBalanceOp(root->_Left, LHeight) == false)
        {
            Height = _Height(root);
            return false;
        }
        else if (_IsBalanceOp(root->_Right, RHeight) == false)
        {
            Height = _Height(root);
            return false;
        }

        Height = LHeight > RHeight ? LHeight + 1 : RHeight + 1;
        return abs(RHeight-LHeight) <= 1;
    }

        bool _IsBalance(Node* root)
        {
            if (root == NULL)
            {
                return true;
            }

            int LHeight = _Height(root->_Left);
            int RHeight = _Height(root->_Right);
            int bf = RHeight - LHeight;
            if (bf != root->_bf)
            {
                cout << "平衡因子异常:" << root->_key << endl;
                return false;
            }
            return (abs(RHeight-LHeight)<2)&&(_IsBalance(root->_Left))&&(_IsBalance(root->_Right));
        }


        size_t _Height(Node* root)
        {
            if (root == NULL)
                return 0;

            if (root->_Right==NULL&&root->_Left==NULL)
                return 1;

            return _Height(root->_Left) > _Height(root->_Right) ?
                _Height(root->_Left) + 1 : _Height(root->_Right) + 1;
        }
        //中序遍历
        void _Inorder(Node* root)
        {
            if (root == NULL)
                return;

            _Inorder(root->_Left);
            cout << "Key:"<<root->_key << " Balance Factor:"<<root->_bf<<endl;
            _Inorder(root->_Right);
        }
        //使树平衡
        void _UpdataBalanceFactor(Node*& root)
        {
            if ((root->_bf == -2) && (root->_Left->_bf == -1))
            {
                //进行右单旋
                _RotateR(root);
            }

            else if ((root->_bf == 2) && (root->_Right->_bf) == 1)
            {
                //进行左单旋
                _RotateL(root);
            }

            else if ((root->_bf == 2) && (root->_Right->_bf == -1))
            {
                //进行右左双旋
                _RotateRL(root);
            }

            else
            {
                //进行左右双旋
                _RotateLR(root);
            }
        }
        //右单旋
        void _RotateR(Node* root)
        {
            Node* SubL = root->_Left;
            Node* SubLR = root->_Left->_Right;
            Node* ppNode = root->_parent;
            root->_Left = SubLR;
            if (SubLR)
                SubLR->_parent = root;
            SubL->_Right = root;
            if (root->_parent == NULL)
            {
                SubL->_parent = NULL;
                _root = SubL;
            }
            else
            {
                SubL->_parent = ppNode;
                if (ppNode->_Left == root)
                    ppNode->_Left = SubL;
                else
                    ppNode->_Right = SubL;
            }
            root->_parent = SubL;
            root->_bf = SubL->_bf = 0;
        }

        void _RotateL(Node* root)
        {
            Node* SubR = root->_Right;
            Node* SubRL = root->_Right->_Left;
            Node* ppNode = root->_parent;

            root->_Right = SubRL;
            if (SubRL)
                SubRL->_parent = root;
            SubR->_Left = root;
            if (root->_parent == NULL)
            {
                _root = SubR;
                SubR->_parent = NULL;
            }
            else
            {
                SubR->_parent = ppNode;
                if (ppNode->_Left == root)
                    ppNode->_Left = SubR;
                else
                    ppNode->_Right = SubR;
            }
            root->_parent = SubR;
            root->_bf = SubR->_bf = 0;
        }

        void _RotateRL(Node* root)
        {
            Node* parent = root;
            Node* SubR = parent->_Right;
            Node* SubRL = SubR->_Left;
            int bf = SubRL->_bf;
            _RotateR(root->_Right);
            _RotateL(root);
        }

        void  _RotateLR(Node* root)
        {
            Node* parent = root;
            Node* SubL = root->_Left;
            Node* SubLR = SubL->_Right;
            int bf = SubLR->_bf;
            _RotateL(root->_Left);
            _RotateR(root);
        }
    protected:
        Node* _root;

};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值