1. 程式人生 > >AVL平衡搜尋樹

AVL平衡搜尋樹


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(); }