【資料結構】AVL樹!!!

doctor_xiong發表於2018-01-27

在二叉搜尋樹來查詢資料的結構裡面,樹形結構並不是一個平衡的二叉樹。在有些情況下效率明顯不是很高(例如,左單支或者右單支)。
在AVL樹裡面,每個子樹的高度相差不大於1,即最高的子樹和最低的子樹之間相差最高為1。
例如:這裡規定是右子樹的高度-左子樹的高度作為平衡因子。
這裡寫圖片描述
這裡寫圖片描述

當在整個樹裡面的結點的平衡因子含有絕對值大於1的時候就需要對樹進行調整。
情況1:
這裡寫圖片描述
情況2:
這裡寫圖片描述
情況3:
這裡寫圖片描述
情況4:
這裡寫圖片描述

當每次進行插入和刪除的同時,需要對結點的平衡因子進行相應的調整。
實現程式碼:
(只實現結點的插入和調整)


#ifndef _AVLTREE_H
#define _AVLTREE_H
#include<iostream>
using namespace std;

template<class T ,class V>
struct AVLTreeNode
{
    AVLTreeNode(T d)
    :left(NULL)
    ,right(NULL)
    ,_parent(NULL)
    ,fd(0)
    ,value(d)
    {}

    AVLTreeNode<T,V>* left;
    AVLTreeNode<T,V>* right;
    AVLTreeNode<T,V>* _parent;
    int fd;
    int value;
};

template<class T,class V>
class AVLTree
{
    public:
    typedef struct AVLTreeNode<T,V> Node;
    AVLTree(T* arr,size_t size)
    {
        _root = NULL;
        if(NULL == arr)
            return ;
        for(int i=0;i<size;i++)
            Insert(arr[i]);
    }
    void Insert(T d)
    {
        _Insert(_root,d);
    }
    void Inorder()
    {
        _Inorder(_root);
        cout<<endl;
    }
    Node* Find(T d)
    {
        return _Find(_root ,d);
    }

private:

    Node* _Find(Node* root,T d)
    {
        while(root)
        {
            if(d < root->value)
                root = root->left;
            else if(d > root->value)
                root = root->right;
            else
                return root;
        }
    }

    void _Inorder(Node* root)
    {
        if(root)
        {
            _Inorder(root->left);
            cout<<root->value<<" ";
            _Inorder(root->right);
        }
    }

    void _rotate_R(Node* parent)//情況1
    {
        Node* pparent = parent->_parent;    //記錄當前節點的前一個結點
        Node*subL = parent->left;
        Node* subLR = subL->right;
        if(subLR)
            subLR->_parent = parent;
        subL->right = parent;
        parent->_parent = subL;
        parent->left = subLR;

        if(pparent == NULL)
            _root = subL;
        else if(pparent->left == parent)
            pparent->left = subL;
        else
            pparent->right = subL;

        subL->_parent = pparent;
        subL->fd = parent->fd = 0;
    }

    void _rotate_L(Node* parent)//情況2
    {
        Node* subR = parent->right;
        Node* subRL = subR->left;
        Node* pparent = parent->_parent;

        if(subRL)
            subRL->_parent = parent;
        subR->left = parent;
        parent->_parent = subR;
        parent->right = subRL;

        if(pparent == NULL)
            _root = subR;
        else if(pparent->left == parent)
            pparent->left = subR;
        else 
            pparent->right = subR;
        subR->_parent = pparent;
        subR->fd = parent->fd = 0;
    }
    void _rotate_RL(Node* parent)        //情況3
    {
        _rotate_R(parent);
        _rotate_L(parent);
    }
    void _rotate_LR(Node* parent)        //情況4
    {
        _rotate_L(parent);
        _rotate_R(parent);
    }

    void _Insert(Node* root,T d)
    {
        Node* tmp = new Node(d);
        Node* parent = NULL;
        if(NULL == root)
        {
            _root = tmp;
            return ;
        }
        while(root)
        {
            parent = root;
            if(root && d < root->value )
                root = root->left;
            else 
                root =  root->right;
        }
        if(d < parent->value)
        {
            parent->left = tmp;
            tmp->_parent = parent;
        }
        else
        {
            parent->right = tmp;
            tmp->_parent = parent;
        }
        while(tmp)
        {
            if(NULL == parent)
                return;
            if(tmp == parent->left)
                parent->fd--;
            else
                parent->fd++;
            if(parent->fd == 0)
                break;
            else if(parent->fd == 1 || parent->fd == -1)
            {
                tmp = parent;
                parent = tmp->_parent;
            }
            else 
            {
                if(parent->fd == 2 )
                {
                    if(tmp->fd = 1)
                    {
                        _rotate_L(parent);
                    }
                    else
                        _rotate_RL(parent);
                }
                else
                {
                    if(tmp->fd == 1)
                        _rotate_LR(parent);
                     else
                        _rotate_R(parent);
                }
            }
        }
    }


    Node* _root;
};

#endif

相關文章