【数据结构】搜索结构之AVL树

AVL树———又称平衡二叉树
二插搜索树虽然可以缩短查找效率,但如果数据有序或接近有序二插搜索树将退化为单支树,查找元素相当于在顺序表中搜索元素,效率低下。

AVL树概念:
《【数据结构】搜索结构之AVL树》

平衡化旋转
如果在一棵原本是平衡的二插搜索树中插入一个新节点,可能造成不平衡,此时必须调整输的结构,使之平衡化。

1.左单旋:
插入点位于ptr的右子结点的右子树—-右右
《【数据结构】搜索结构之AVL树》
2.右单旋:
插入点位于ptr的左子结点的左子树—-左左
《【数据结构】搜索结构之AVL树》
3.先左后右双旋:
插入点位于ptr左子节点的右子树—-左右
《【数据结构】搜索结构之AVL树》
4.先右后左双旋:
插入点位于ptr右子节点的左子树—-右左
《【数据结构】搜索结构之AVL树》

AVL树的插入
《【数据结构】搜索结构之AVL树》
AVL树的删除
《【数据结构】搜索结构之AVL树》

AVL树代码:
【AVLTree.h】

#pragma once
#include<iostream>
using namespace std;

template<class K,class V>
struct AVLNode
{
    AVLNode(K key,V value)
    :_Lchild(NULL)
    , _Rchild(NULL)
    , _parent(NULL)
    , _key(key)
    , _value(value)
    , _bf(0)
    {}

    AVLNode<K, V>* _Lchild;
    AVLNode<K, V>* _Rchild;
    AVLNode<K, V>* _parent;
    K _key;
    V _value;
    int _bf;
};

template<class K,class V>
class AVLTree
{
    typedef AVLNode<K, V>* pNode;
    typedef AVLNode<K, V> Node;
public:
    AVLTree()
        :Root(NULL)
    {}
    bool Insert(K& k,V& v)   //插入元素
    {
        return _Insert(k, v);
    }

    void InOrder()   //中序遍历
    {
        _InOrder(Root);
    }
    bool CheckAVLT()   //判断是否是AVL树
    {
        return _CheckAVLT(Root);
    }
/////////////////////////////////////////////////////////////
private:
    bool _CheckAVLT(pNode pRoot)
    {
        if (pRoot)
        {
            int len = _Height(pRoot->_Rchild) - _Height(pRoot->_Lchild);
            if (len<-1 || len>1)
                return false;
                   _CheckAVLT(pRoot->_Lchild);
                   _CheckAVLT(pRoot->_Rchild);
        }
        return true;
    }
    int _Height(pNode pRoot)
    {
        if (pRoot == NULL)
            return 0;
        return  _Height(pRoot->_Lchild) > _Height(pRoot->_Rchild) ? _Height(pRoot->_Lchild) + 1 : _Height(pRoot->_Rchild) + 1;

    }
    void _InOrder(pNode pRoot)
    {
        if (pRoot != NULL)
        {
            _InOrder(pRoot->_Lchild);
            cout << "<" << pRoot->_key << "," << pRoot->_value << ">" << endl;
            _InOrder(pRoot->_Rchild);
        }
    }
    bool _Insert(K& k, V& v)
    {
        pNode newNode = new Node(k, v);
        if (Root == NULL)
        {
            Root = newNode;
            return true;
        }
        pNode cur = Root;
        pNode pParent = NULL;
        while (cur)                  //查找要插入的位置
        {
            pParent = cur;
            if (cur->_key > k)
                cur = cur->_Lchild;

            else if (cur->_key < k)
                cur = cur->_Rchild;
            else
                return false;
        }

        if (pParent->_key>k)
        {
            pParent->_Lchild = newNode;
            newNode->_parent = pParent;
        }

        else if (pParent->_key < k)
        {
            pParent->_Rchild = newNode;
            newNode->_parent = pParent;
        }
        cur = newNode;       //cur标记双亲节点的孩子
        while (pParent)
        {
            if (pParent->_Lchild == cur)
                    pParent->_bf--;
            else if (pParent->_Rchild == cur)
                    pParent->_bf++;

                if (pParent->_bf == 1 || pParent->_bf == -1)
                {
                    cur = pParent;
                    pParent = pParent->_parent;
                }
                else if (pParent->_bf == 2 || pParent->_bf == -2)   //旋转
                {
                    if (pParent->_bf == 2)       
                    {
                        if (pParent->_Rchild->_bf==1)
                            RotateL(pParent);          //左单旋
                        else
                            RotateRL(pParent);           //右左双旋
                    }
                    else                        
                    {
                        if (pParent->_Lchild->_bf == -1)
                            RotateR(pParent);          //右单旋
                        else
                            RotateLR(pParent);         //左右双旋
                    }
                }
                else
                    break;
        }
        return true;
    }
    void RotateL(pNode pParent)         //左单旋
    {
        pNode pSubR = pParent->_Rchild;
        pNode pSubRL = pSubR->_Lchild;
        pNode _pParent = pParent->_parent;

        pParent->_Rchild = pSubRL;
        if (pSubRL!=NULL)
        pSubRL->_parent = pParent;

        pSubR->_Lchild = pParent;
        pParent->_parent = pSubR;
        if (_pParent == NULL)
        {
            Root = pSubR;
            pSubR->_parent = _pParent;
        }
        else if (_pParent != NULL&&_pParent->_Lchild == pParent)
        {
            _pParent->_Lchild = pSubR;
            pSubR->_parent = _pParent;
        }
        else if (_pParent != NULL&&_pParent->_Rchild == pParent)
        {
            _pParent->_Rchild = pSubR;
            pSubR->_parent = _pParent;
        }
        pSubR->_bf = 0;
        pParent->_bf = 0;
    }
    void RotateR(pNode pParent)   //右单旋
    {
        pNode pSubL = pParent->_Lchild;
        pNode pSubLR = pSubL->_Rchild;
        pNode _pParent = pParent->_parent;

        pParent->_Lchild = pSubLR;
        if (pSubLR!=NULL)
        pSubLR->_parent = pParent;

        pSubL->_Rchild = pParent;
        pParent->_parent = pSubL;

        if (_pParent == NULL)
        {
            Root = pSubL;
            pSubL->_parent = _pParent;
        }
        else if (_pParent != NULL&&_pParent->_Lchild == pParent)
        {
            _pParent->_Lchild = pSubL;
            pSubL->_parent = _pParent;
        }
        else if (_pParent != NULL&&_pParent->_Rchild == pParent)
        {
            _pParent->_Rchild = pSubL;
            pSubL->_parent = _pParent;
        }
        pSubL->_bf = 0;
        pParent->_bf = 0;
    }
    void RotateRL(pNode pnode)      //右左双旋
    {
        pNode pParent = pnode;
        pNode pSubR = pnode->_Rchild;
        RotateR(pnode->_Rchild);
        RotateL(pnode);

        if (pSubR->_Lchild->_bf== 1)
        {
            pParent->_bf = -1;
        }
        else if (pSubR->_Lchild->_bf == -1)
        {
            pSubR->_bf = 1;
        }

    }
    void RotateLR(pNode pnode)    //左右双旋
    {
        pNode pParent = pnode;
        pNode pSubL= pnode->_Lchild;
        RotateL(pnode->_Lchild);
        RotateR(pnode);

        if (pSubL->_Rchild->_bf == -1)
        {
            pParent->_bf = 1;
        }
        else if (pSubL->_Rchild->_bf == 1)
        {
            pSubL->_bf = -1;
        }
    }

private:
    pNode Root;
};

void test()
{
    //int arr[] = {5,3,4,1,7,8,2,6,0,9}; //普通版
    //int arr[] = {30,20,50,40,60,70}; //左单旋
    //int arr[] = {60,40,70,30,50,20}; //右单旋
    //int arr[] = { 3, 2, 6, 5, 4, 7 }; //右左双旋
    int arr[] = {4,2,6,1,3,5,15,7,16,14}; //左右双旋 int size = sizeof(arr) / sizeof(arr[0]); AVLTree<int, int> t; for (int i = 0; i < size; i++) { t.Insert(arr[i], i); } t.InOrder(); if (t.CheckAVLT()) cout << "是平衡二叉树" << endl; else cout << "不是平衡二叉树" << endl; }

【test.cpp】

#include"AVLTree.h"

int main()
{
    test();
    system("pause");
    return 0;

}
    原文作者:AVL树
    原文地址: https://blog.csdn.net/lz201788/article/details/79451815
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞