c++--AVL树简单实现

1.什么是AVL树

AVL树就是在搜索二叉树的基础上通过控制左右子树的高度差实现的,在搜索二叉树的基础上,通过旋转来控制,是左右子树高度差的绝对值严格控制为不超过1(通过旋转来控制树的高度)。由于搜索二叉树的效率最差为O(N-1)次,(n为节点个数),所以为了减少查找时间而创造了AVL树,

当向二叉搜索树中插入新结点后,如果能保证每个结点的左右子树高度之差的绝对值不超过1(需要对树中的结点进行调整),即可降低树的高度,从而减少平均搜索长度。

2.AVL树的定义

一颗AVL树或者是空树,是具有以下性质的树:

1.他的左右子树都是AVL树

2.左右高度差的绝对值不超过1(即1,0,-1)

如果一棵二叉搜索树是高度平衡的,它就是AVL树。如果它有n个结点,其高度可保持在
O(log_2 n),搜索时间复杂度O(log_2 n)。

AVL树就是在二叉搜索树的基础上引入了平衡因子,因此AVL树也可以看成是二叉搜索树。那么,AVL树的插入过程可以分为两步:
1. 按照二叉搜索树的方式插入新节点
2. 调整节点的平衡因子

标准AVL树

 3. AVL树的实现

AVL树最重要的就是旋转,需要控制左右子树高度差的绝对值不超过1,因此,平衡因子可能存在三种情况,即0,正负1,正负2,

1. 如果平衡因子为0,说明插入之前pParent的平衡因子为正负1,插入后被调整成0,此时满足AVL树的性质,插入成功

2. 如果平衡因子为正负1,说明插入前pParent的平衡因子一定为0,插入后被更新成正负1,此时以pParent为根的树的高度增加,需要继续向上更新。
3. 如果pParent的平衡因子为正负2,则pParent的平衡因子违反平衡树的性质,需要对其进行旋转处理。

如果在一棵原本是平衡的AVL树中插入一个新节点,可能造成不平衡,此时必须调整树的结构,
使之平衡化。根据节点插入位置的不同,AVL树的旋转分为四种:

1.新节点插入较高左子树的左侧---左左:右单旋

 2.新插入节点较高右子树的右侧:左旋转

 3.新节点插入较高左子树的右侧---左右:先左单旋再右单旋

 4.. 新节点插入较高右子树的左侧---右左:先右单旋再左单旋

 4.代码实现

#pragma once
#include <iostream>
#include <assert.h>
using namespace std;
namespace _3s
{
    template<class K, class V>
    struct AVLTreeNode
    {
        AVLTreeNode* _left;
        AVLTreeNode* _right;
        AVLTreeNode* _parent;
        std::pair<K, V> _KV;
        int bf;
        AVLTreeNode(const std::pair<K, V> kv)
            :_left(nullptr)
            , _right(nullptr)
            , _parent(nullptr)
            , _KV(kv)
            , bf(0)
        {}
    };
    //节点 
    template<class K, class V>
    class AVLTree
    {
        typedef AVLTreeNode<K, V> Node;
    public:
        //插入
        bool insert(const std::pair<K, V>& kv)
        {
            if (root == nullptr)
            {
                root = new Node(kv);
                return true;
            }
            Node* parent = nullptr;
            Node* cur = root;
            while (cur)
            {
                if (cur->_left.first < kv.first)
                {
                    parent = cur;
                    cur = cur->_right;
                }
                else if (cur->_left.first > kv.first)
                {
                    parent = cur;
                    cur = cur->_left;
                }
                else
                {
                    return false;
                }
            }
            cur = new Node(kv);
            if (parent->_kv.first > kv.first)
            {
                parent->left = cur;
                parent->bf--;
            }
            else
            {
                parent->right = cur;
                parent->bf++;
            }
            cur->_parent = parent;
            while (parent)
            {


                if (abs(parent->bf) == 1)
                {
                    parent = parent->_parent;
                    cur = cur->_parent;

                }
                else if (abs(parent->bf) == 2)
                {
                    if (parent->_bf == 2 && cur->_bf == 1)
                    {
                        RotateL(parent);
                    }
                    else if ((parent->_bf == -2 && cur->_bf == -1))
                    {
                        RotateR(parent);
                    }
                    else if (parent->_bf == -2 && cur->_bf == 1)
                    {
                        RotateLR(parent);
                    }
                    break;
                }
                else
                {
                    assert(false);
                }
            }
            return true;
        }
    private:
        //左旋转
        void RotateL(Node* parent)
        {
            Node* subR = parent->_right;
            Node* subRL = subR->_left;
            parent->_right = subRL;
            if (subRL)
                subRL->_parent = parent;
            Node* ppNode = parent->_parent;
            subR->_left = parent;
            parent->_parent = subR;
            if (root == parent)
            {
                root = subR;
                subR->_parent = nullptr;
            }
            else
            {
                if (ppNode->_left == parent)
                {
                    ppNode->_left = subR;
                }
                else
                {
                    ppNode->_right = subR;
                }
                subR->_parent = ppNode;
            }
            subR->_bf = parent->_bf = 0;
        }
        //右旋转
        void RotateR(Node* parent)
        {
            Node* subL = parent->_left;
            Node* subLR = subR->_right;

            parent->_left = subRL;
            if (subRL)
                subRL->_parent = parent;
            Node* ppNode = parent->_parent;
            subL->_right = parent;
            parent->_parent = subL;
            if (root == parent)
            {
                root = subL;
                subL->_parent = nullptr;
            }
            else
            {
                if (ppNode->_left == parent)
                {
                    ppNode->_left = subL;
                }
                else
                {
                    ppNode->_right = subL;
                }
                subR->_parent = ppNode;
            }
            subL->_bf = parent->_bf = 0;
        }
         //左右旋转
        void RotateLR(Node* parent)
        {
            Node* subL = parent->_left;
            Node* subLR = subL->_right;
            int _bf = subLR->bf;
            RotateL(parent->_left);
            RotateR(parent);

            subLR->bf = 0;
            if (_bf == 1)
            {
                parent->_bf = 0;
                subL->_bf = -1;
            }
            else if (_bf == -1)
            {
                parent->bf = 1;
                subL->bf = 0;
            }
            else if (_bf == 0)
            {
                parent->bf = 0;
                subL->bf = 0;
            }
            else
            {
                assert(false);
            }


        }
        //右左旋转
        void RotateRL(Node* parent)
        {

            Node* subR = parent->_right;
            Node* subRL = subL->_left;
            int _bf = subLR->bf;
            RotateR(parent->_right);
            RotateL(parent);

            subRL->_bf = 0;
            if (bf == 1)
            {
                subR->_bf = 0;
                parent->_bf = -1;
            }
            else if (bf == -1)
            {
                subR->_bf = 1;
                parent->_bf = 0;
            }
            else if (bf == 0)
            {
                parent->_bf = 0;
                subR->_bf = 0;
            }
            else
            {
                assert(false);
            }

        }
    private:
        Node* root = nullptr;
    };
}


猜你喜欢

转载自blog.csdn.net/weixin_66828150/article/details/132197765
今日推荐