AVL平衡搜索树

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Comedly/article/details/52124059

AVL树又称高度平衡的二叉搜索树

性质:
     1. 左子树和右子树的高度之差的绝对值不超过1
     2. 树中的每个左子树和右子树都是AVL树
     3. 每个节点都有一个平衡因子(balance factor--bf),任一节点的平衡因子是-1,0,1。(每个节点的平衡因子等于右子树的高度减去左子树的高度 )

     当插入一个节点时,如果这个节点的父节点的平衡因子不满足AVL树的特点,这时就需要对AVL树进行调整,即旋转。

     1、左单旋转
     
2、右单旋转
        
3、左右旋转

4、右左旋转

实现代码如下:
#pragma once

template<class K,class V>
struct AVLTreeNode
{
    AVLTreeNode<K,V>* _left;
    AVLTreeNode<K,V>* _right;
    AVLTreeNode<K,V>* _parent;

    K _key;
    V _value;

    int _bf;//平衡因子
    AVLTreeNode(const K& key,const V& value)
        :_bf(0)
        ,_left(NULL)
        ,_right(NULL)
        ,_parent(NULL)
        ,_key(key)
        ,_value(value)
    { }
};

template<class K,class V>
class AVLTree
{
public:
    typedef AVLTreeNode<K,V> Node;
    AVLTree()
        :_root(NULL)
    { }

    bool Insert(const K& key,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->_right;
            }
            else if(cur->_key > key)
            {
                parent = cur;
                cur = cur->_left;
            }
            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(cur == parent->_left)
                parent->_bf--;
            else
                parent->_bf++;
            if(parent->_bf == 0)
                break;
            else if(parent->_bf == -1 || parent->_bf == 1)//回朔
            {
                cur = parent;
                parent = cur->_parent;
            }
            else//平衡因子为2或-2
            {
                if(cur->_bf == 1)
                {
                    if(parent->_bf == 2)
                        RotateL(parent);
                    else//-2
                        RotateLR(parent);
                }
                else
                {
                    if(parent->_bf == -2)
                        RotateR(parent);
                    else
                        RotateRL(parent);
                }
                break;
            }
        }
        return true;
    }

    Node* Find(const K& key)
    {
        if(_root == NULL)
            return NULL;
        Node* cur = _root;
        while (cur)
        {
            if(cur->_key < key)
            {
                cur = cur->_right;
            }
            else if(cur->_key > key)
            {
                cur = cur->_left;
            }
            else
            {
                return cur;
            }
        }
        return NULL;
    }

    void InOrder()
    {
        _InOrder(_root);
        cout<<endl;
    }

    bool IsBlance()
    {
        return _IsBlance(_root);
    }


    ~AVLTree()
    {
        _Destroy(_root);
        _root = NULL;
    }

protected:
    void RotateL(Node* parent)
    {
        Node* subR = parent->_right;
        Node* subRL = subR->_left;

        parent->_right = subRL;
        if(subRL)
            subRL->_parent = parent;

        subR->_left = parent;

        Node* ppNode = parent->_parent;
        parent->_parent = subR;
        subR->_parent = ppNode;
        if(ppNode == NULL)
        {
            _root = subR;
        }
        else
        {
            if(ppNode->_left == parent)
                ppNode->_left = subR;
            else
                ppNode->_right = subR;
        }
        parent->_bf = subR->_bf = 0;
    }

    void RotateR(Node* parent)
    {
        Node* subL = parent->_left;
        Node* subLR = subL->_right;
        parent->_left = subLR;
        if(subLR)
            subLR->_parent = parent;
        subL->_right = parent;
        Node* ppNode = parent->_parent;
        parent->_parent = subL;
        subL->_parent = ppNode;

        if(ppNode == NULL)
        {
            _root = subL;
        }
        else
        {
            if(ppNode->_left == parent)
                ppNode->_left = subL;
            else
                ppNode->_right = subL;
        }
        parent->_bf = subL->_bf = 0;
    }

    void RotateLR(Node* parent)
    {
        Node* subL = parent->_left;
        Node* subLR =subL->_right;
        int bf = subLR->_bf;

        RotateL(parent->_left);
        RotateR(parent);

        //根据subL的平衡因子修正其他节点的平衡因子
        if(bf == -1)
        {
            subL->_bf = 0;
            parent->_bf = 1;
        }
        else if(bf == 1)
        {
            subL->_bf = -1;
            parent->_bf = 0;
        }
        else
        {
            subL->_bf = parent->_bf = 0;
        }
    }

    void RotateRL(Node* parent)
    {
        Node* subR = parent->_right;
        Node* subRL = subR->_left;
        int bf = subRL->_bf;
        RotateR(parent->_right);
        RotateL(parent);

        //根据subRL的平衡因子修正其它节点的平衡因子
        if(bf == 1)
        {
            subR->_bf = 0;
            parent->_bf = -1;
        }
        else if(bf == -1)
        {
            subR->_bf = 1;
            parent->_bf = 0;
        }
        else
        {
            parent->_bf = subR->_bf = 0;
        }
    }

    void _Destroy(Node* root)
    {
        if(root == NULL)
            return;
        _Destroy(root->_left);
        _Destroy(root->_right);
        delete root;
    }

    void _InOrder(Node* root)
    {
        if(root == NULL)
            return;
        _InOrder(root->_left);
        cout<<root->_key<<" ";
        _InOrder(root->_right);
    }

    int _Height(Node* root)
    {
        if(root == NULL)
            return 0;
        int Left = _Height(root->_left);
        int Right = _Height(root->_right);
        return (Left > Right) ? (Left + 1) : (Right + 1);
    }

    bool _IsBlance(Node* root)
    {
        if(root == NULL)
            return true;
        int left = _Height(root->_left);
        int right = _Height(root->_right);
        if((right - left) != root->_bf || abs(right - left) > 1)
        {
            cout<<"该节点的平衡因子异常:";
            cout<<root->_key<<" "<<endl;
            return false;
        }
        return _IsBlance(root->_left) && _IsBlance(root->_right);
    }

protected:
    Node* _root;
};

void AVLTreeTest()
{
    int a[] = {16, 3, 7, 11, 9, 26, 18, 14, 15};
    AVLTree<int,int> tree;
    for(int i = 0;i < 9;i++)
    {
        tree.Insert(a[i],i);
    }
    tree.InOrder();
    tree.Find(16);
    tree.IsBlance();

}

void TestTree_SP()
{
    int a[] = {4, 2, 6, 1, 3, 5, 15, 7, 16, 14};
    AVLTree<int, int> t;

    for (int i = 0; i < sizeof(a)/sizeof(a[0]); ++i)
    {
        t.Insert(a[i], i);
    }
    t.InOrder();
    t.IsBlance();
}


猜你喜欢

转载自blog.csdn.net/Comedly/article/details/52124059