AVL树

记得上次的博客中说到了二叉所搜树,也说到了他还说一种有欠缺的二叉树,当输入单调递增或单调递减的数据后,他会退化成链表,这样会严重影响效率,所以AVL树就被引出来了,下面就开始简单介绍AVL树吧。
首先AVL树是一种严格的平衡二叉树,他要求所有节点所在的二叉树都满足一个条件:平衡因子不大于2,搜索二叉树也就接近满二叉树了,这个时候搜索的效率就比较高了,但是它也因此付出了很高的代价,那就是他会不断的旋转,下面我们就开始AVL树的旋转吧!
我们来分析AVL树不平衡的时候旋转的情况吧,我总结了一下,大概如下几种情况吧:



以上就是几种情况的分析,为什么在左右双旋的时候或者右左双旋的时候我要画出两种插入节点的位置呢?不是无聊,而是在双旋的时候插入位置对平衡因子有影响,这个问题在单旋中是不存在的,下面就来看看吧:

1.右左单旋

   也就是上面第三幅图,我们可以推理得出:

(1).当插入节点10的时候,10最终会被分配到左子树中,具体位置是在8右边,节点


(2).当插入节点13的时候


右左单旋和这个刚好对称,情况相似,所以就不举例说明了,下面给出代码吧,代码针对AVL树插入节点的四种情况进行了分析:

#pragma once  
#include <iostream>  
using namespace std;  
  
template<class K,class V>  
struct AVLTreeNode  
{  
    typedef AVLTreeNode<K, V> Node;  
  
    AVLTreeNode<K, V> *_left;  
    AVLTreeNode<K, V> *_right;  
    AVLTreeNode<K, V> *_parent;  
  
    K   _key;  
    V   _val;  
    int _bf;  
      
    AVLTreeNode(const K &key = K(), const V &val = V())  
        : _key(key)  
        , _val(val)  
        , _bf(0)  
        , _left(NULL)  
        , _right(NULL)  
        , _parent(NULL)  
    {}  
};  
  
template<class K,class V>  
class AVLTree  
{  
    typedef AVLTreeNode<K, V> Node;  
public:  
    AVLTree()  
        : _root(NULL)  
    {}  
  
    bool Insert(const K key, const V val)  
    {  
        if (_root == NULL)  
        {  
            _root = new Node(key, val);  
            return true;  
        }  
  
        Node* parent = NULL;  
        Node* cur = _root;  
        while (cur)  
        {  
            parent = cur;  
            if (key > cur->_key)  
            {  
                cur = cur->_right;  
            }  
            else if (key < cur->_key)  
            {  
                cur = cur->_left;  
            }  
            else  
            {  
                return false;  
            }  
        }  
  
        cur = new Node(key, val);  
        cur->_parent = parent;  
        if (key < parent->_key)  
        {  
            parent->_left = cur;  
        }  
        else  
        {  
            parent->_right = cur;  
        }  
  
        while (parent)  
        {  
            if (parent->_left == cur)  
            {  
                --parent->_bf;  
            }  
            else  
            {  
                ++parent->_bf;  
            }  
  
            if (parent->_bf == 0)  
            { //平衡  
                return true;  
            }  
            else if (abs(parent->_bf) < 2)  
            { //继续上调  
                cur = parent;  
                parent = parent->_parent;  
            }  
            else  
            { //不平衡,分四种情况讨论               
                if (cur->_bf > 0 && parent->_bf > 0)  
                {   //情况1 左单旋  
                    _RotateL(parent, cur);                    
                    return true;  
                }  
                else if (parent->_bf < 0 && cur < 0)  
                {   //情况2 右单旋  
                    _RotateR(parent, cur);  
                    return true;  
                }                                 
                else if (parent->_bf < 0 && cur->_bf > 0)  
                {   //情况3 左右单旋  
                    Node* pSubL = parent->_left;  
                    Node* pSubLR = pSubL->_right;  
                    int bf = pSubLR->_bf;  
                    // bf = -1 , 0 , 1 产生的影响  
                      
                    _RotateL(pSubL, pSubLR);  
                    _RotateR(parent, pSubLR); //此处千万不要传递(parent,parent->_left)因为两者都是parent的引用  
                    if (bf == -1)  
                    { //  
                        //cur->_bf = 0;  
                        parent->_bf = 1;  
                    }  
                    else if (bf == 1)  
                    {  
                        cur->_bf = -1;  
                        //parent->_bf = 0;  
                    }  
                    else  
                    {}  
                      
                    return true;  
                }  
                else //parent->_bf > 0 && cur->_bf < 0  
                {   //情况4 右左单旋  
                    Node* pSubR = parent->_right;  
                    Node* pSubRL = pSubR->_left;  
                    int bf = pSubRL->_bf;  
                    // bf = -1 , 0 , 1 产生不同的影响  
                    _RotateR(pSubR, pSubRL);  
                    _RotateL(parent, pSubRL);  
  
                    if (bf == -1)  
                    {  
                        cur->_bf = 1;  
                        //parent->_bf = 0;  
                    }  
                    else if (bf == 1)  
                    {  
                        parent->_bf = -1;  
                        //cur->_bf = 0;  
                    }  
                    else  
                    {}  
  
                    return true;  
                }  
            }  
        }  
    }  
  
    bool Isbalance()  
    {  
        return _Isbalance(_root);  
    }  
  
    int Height(Node* root)  
    {  
        return _Height(root);  
    }  
    ~AVLTree()  
    {  
        //_Destroy();  
    }  
  
protected:  
    int _Height(Node *root)  
    {  
        if (root == NULL)  
            return 0;  
        int left = 1 + _Height(root->_left);  
        int right = 1 + _Height(root->_right);  
  
        return left > right ? left : right;  
    }  
  
    bool _Isbalance(Node *root)  
    {  
        if (root == NULL)  
        {  
            return true;  
        }  
  
        int bf = _Height(root->_right) - _Height(root->_left);  
        if ( root->_bf != bf )  
        {  
            cout << "is unbalance:" << root->_key << endl;  
            return false;  
        }  
          
        return _Isbalance(root->_left);  
        return _Isbalance(root->_right);  
    }  
  
    void _RotateL(Node*& parent,Node*& cur)  
    {  
        cur->_parent = parent->_parent;  
        if (parent->_parent)  
        { //parent 还有父节点  
            if (parent == parent->_parent->_left)  
                parent->_parent->_left = cur;  
            else  
                parent->_parent->_right = cur;  
        }  
        else  
        { //parent为根节点  
            _root = cur;  
        }  
  
        parent->_parent = cur;  
        if (cur->_left)  
            cur->_left->_parent = parent;  
        parent->_right = cur->_left;        
        cur->_left = parent;  
          
        //平衡因子置为 0  
        parent->_bf = 0;  
        cur->_bf = 0;  
    }  
      
    void _RotateR(Node*& parent, Node*& cur)  
    {  
        cur->_parent = parent->_parent;  
        if (parent->_parent)  
        { //parent 还有父节点  
            if (parent == parent->_parent->_left)  
                parent->_parent->_left = cur;  
            else  
                parent->_parent->_right = cur;  
        }  
        else  
        { //parent为根节点  
            _root = cur;  
        }  
  
        //Node* pNode = cur;  
        parent->_parent = cur;  
          
        if (cur->_right != NULL)  
            cur->_right->_parent = parent;  
        parent->_left = cur->_right;  
        //pNode->_right = parent;  
        cur->_right = parent;  
          
        //平衡因子  
        parent->_bf = 0;  
        cur->_bf = 0;  
    }  
    void _RotateLR()  
    {}  
    void _RotateRL()  
    {}  
  
protected:  
    Node    *_root;  
};  
  
void TestAVLTree()  
{  
    AVLTree<int, int> At;  
    //At.Insert(10, 1);  
    //At.Insert(15, 1);  
    //At.Insert(20, 1);  
    //At.Insert(8, 1);  
    //At.Insert(12, 1);  
    左右双旋  
    At.Insert(13, 1);  //影响平衡因子  
    At.Insert(11, 1);  //影响平衡因子  
    /************************************************/  
    At.Insert(10, 1);  
    At.Insert(15, 1);  
    At.Insert(20, 1);  
    At.Insert(18,1);  
    At.Insert(25, 1);  
    //右左双旋  
    //At.Insert(17, 1);   //影响平衡因子  
    //At.Insert(19, 1);   //影响平衡因子   
      
      
    At.Isbalance();  
}  
[cpp] view plain copy 在CODE上查看代码片派生到我的代码片
#pragma once  
#include <iostream>  
using namespace std;  
  
template<class K,class V>  
struct AVLTreeNode  
{  
    typedef AVLTreeNode<K, V> Node;  
  
    AVLTreeNode<K, V> *_left;  
    AVLTreeNode<K, V> *_right;  
    AVLTreeNode<K, V> *_parent;  
  
    K   _key;  
    V   _val;  
    int _bf;  
      
    AVLTreeNode(const K &key = K(), const V &val = V())  
        : _key(key)  
        , _val(val)  
        , _bf(0)  
        , _left(NULL)  
        , _right(NULL)  
        , _parent(NULL)  
    {}  
};  
  
template<class K,class V>  
class AVLTree  
{  
    typedef AVLTreeNode<K, V> Node;  
public:  
    AVLTree()  
        : _root(NULL)  
    {}  
  
    bool Insert(const K key, const V val)  
    {  
        if (_root == NULL)  
        {  
            _root = new Node(key, val);  
            return true;  
        }  
  
        Node* parent = NULL;  
        Node* cur = _root;  
        while (cur)  
        {  
            parent = cur;  
            if (key > cur->_key)  
            {  
                cur = cur->_right;  
            }  
            else if (key < cur->_key)  
            {  
                cur = cur->_left;  
            }  
            else  
            {  
                return false;  
            }  
        }  
  
        cur = new Node(key, val);  
        cur->_parent = parent;  
        if (key < parent->_key)  
        {  
            parent->_left = cur;  
        }  
        else  
        {  
            parent->_right = cur;  
        }  
  
        while (parent)  
        {  
            if (parent->_left == cur)  
            {  
                --parent->_bf;  
            }  
            else  
            {  
                ++parent->_bf;  
            }  
  
            if (parent->_bf == 0)  
            { //平衡  
                return true;  
            }  
            else if (abs(parent->_bf) < 2)  
            { //继续上调  
                cur = parent;  
                parent = parent->_parent;  
            }  
            else  
            { //不平衡,分四种情况讨论               
                if (cur->_bf > 0 && parent->_bf > 0)  
                {   //情况1 左单旋  
                    _RotateL(parent, cur);                    
                    return true;  
                }  
                else if (parent->_bf < 0 && cur < 0)  
                {   //情况2 右单旋  
                    _RotateR(parent, cur);  
                    return true;  
                }                                 
                else if (parent->_bf < 0 && cur->_bf > 0)  
                {   //情况3 左右单旋  
                    Node* pSubL = parent->_left;  
                    Node* pSubLR = pSubL->_right;  
                    int bf = pSubLR->_bf;  
                    // bf = -1 , 0 , 1 产生的影响  
                      
                    _RotateL(pSubL, pSubLR);  
                    _RotateR(parent, pSubLR); //此处千万不要传递(parent,parent->_left)因为两者都是parent的引用  
                    if (bf == -1)  
                    { //  
                        //cur->_bf = 0;  
                        parent->_bf = 1;  
                    }  
                    else if (bf == 1)  
                    {  
                        cur->_bf = -1;  
                        //parent->_bf = 0;  
                    }  
                    else  
                    {}  
                      
                    return true;  
                }  
                else //parent->_bf > 0 && cur->_bf < 0  
                {   //情况4 右左单旋  
                    Node* pSubR = parent->_right;  
                    Node* pSubRL = pSubR->_left;  
                    int bf = pSubRL->_bf;  
                    // bf = -1 , 0 , 1 产生不同的影响  
                    _RotateR(pSubR, pSubRL);  
                    _RotateL(parent, pSubRL);  
  
                    if (bf == -1)  
                    {  
                        cur->_bf = 1;  
                        //parent->_bf = 0;  
                    }  
                    else if (bf == 1)  
                    {  
                        parent->_bf = -1;  
                        //cur->_bf = 0;  
                    }  
                    else  
                    {}  
  
                    return true;  
                }  
            }  
        }  
    }  
  
    bool Isbalance()  
    {  
        return _Isbalance(_root);  
    }  
  
    int Height(Node* root)  
    {  
        return _Height(root);  
    }  
    ~AVLTree()  
    {  
        //_Destroy();  
    }  
  
protected:  
    int _Height(Node *root)  
    {  
        if (root == NULL)  
            return 0;  
        int left = 1 + _Height(root->_left);  
        int right = 1 + _Height(root->_right);  
  
        return left > right ? left : right;  
    }  
  
    bool _Isbalance(Node *root)  
    {  
        if (root == NULL)  
        {  
            return true;  
        }  
  
        int bf = _Height(root->_right) - _Height(root->_left);  
        if ( root->_bf != bf )  
        {  
            cout << "is unbalance:" << root->_key << endl;  
            return false;  
        }  
          
        return _Isbalance(root->_left);  
        return _Isbalance(root->_right);  
    }  
  
    void _RotateL(Node*& parent,Node*& cur)  
    {  
        cur->_parent = parent->_parent;  
        if (parent->_parent)  
        { //parent 还有父节点  
            if (parent == parent->_parent->_left)  
                parent->_parent->_left = cur;  
            else  
                parent->_parent->_right = cur;  
        }  
        else  
        { //parent为根节点  
            _root = cur;  
        }  
  
        parent->_parent = cur;  
        if (cur->_left)  
            cur->_left->_parent = parent;  
        parent->_right = cur->_left;        
        cur->_left = parent;  
          
        //平衡因子置为 0  
        parent->_bf = 0;  
        cur->_bf = 0;  
    }  
      
    void _RotateR(Node*& parent, Node*& cur)  
    {  
        cur->_parent = parent->_parent;  
        if (parent->_parent)  
        { //parent 还有父节点  
            if (parent == parent->_parent->_left)  
                parent->_parent->_left = cur;  
            else  
                parent->_parent->_right = cur;  
        }  
        else  
        { //parent为根节点  
            _root = cur;  
        }  
  
        //Node* pNode = cur;  
        parent->_parent = cur;  
          
        if (cur->_right != NULL)  
            cur->_right->_parent = parent;  
        parent->_left = cur->_right;  
        //pNode->_right = parent;  
        cur->_right = parent;  
          
        //平衡因子  
        parent->_bf = 0;  
        cur->_bf = 0;  
    }  
    void _RotateLR()  
    {}  
    void _RotateRL()  
    {}  
  
protected:  
    Node    *_root;  
};  
  
void TestAVLTree()  
{  
    AVLTree<int, int> At;  
    //At.Insert(10, 1);  
    //At.Insert(15, 1);  
    //At.Insert(20, 1);  
    //At.Insert(8, 1);  
    //At.Insert(12, 1);  
    左右双旋  
    At.Insert(13, 1);  //影响平衡因子  
    At.Insert(11, 1);  //影响平衡因子  
    /************************************************/  
    At.Insert(10, 1);  
    At.Insert(15, 1);  
    At.Insert(20, 1);  
    At.Insert(18,1);  
    At.Insert(25, 1);  
    //右左双旋  
    //At.Insert(17, 1);   //影响平衡因子  
    //At.Insert(19, 1);   //影响平衡因子   
      
      
    At.Isbalance();  
}  



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值