AVL树详解&面试题-判断一棵树是否是平衡二叉树

来源:互联网 发布:策略经营单机手游 知乎 编辑:程序博客网 时间:2024/06/04 19:34

上次写了关于二叉搜索树的分析,但是二叉搜索树有一个缺陷,就是当插入一个有序(或接近有序)的序列时,二叉搜索树就相当于一个链表了,搜索效率会特别低。那么,如何来改进呢?这就引入了AVL树(高度平衡二叉树),那么下面我们一起来了解一下AVL树吧!
AVL树的特征:
1、左右子树的高度差都不超过1;
2、左右子树都是AVL树;
3、每个节点都有一个平衡因子bf(blance fator ),其值为右子树的高度减去左子树的高度。
AVL树也是二叉搜索树,只是在插入节点时,进行了一些调整,使它的把树的高度降下来,做右子树高度差不超过1。做怎样的调整呢?这就要看一下AVL树的旋转啦!
当插入一个节点后,树的平衡因子bf=2时就对该树进行旋转,旋转又分为如下几种情况:
AVL树的旋转:
这里写图片描述

下面我给出我写的代码,只实现了插入操作,删除操作后期会加进来。
代码实现AVL树&判断一棵树是否是平衡二叉树:

#include<iostream>using namespace std;template<class K, class V>struct AVLTreeNode{    K _key;    V _value;    int _bf;   //平衡因子    AVLTreeNode * _parent;    AVLTreeNode * _left;    AVLTreeNode * _right;    AVLTreeNode(K k=K(),V v=V())        :_key(k)        ,_value(v)        ,_bf(0)        ,_parent(NULL)        ,_left(NULL)        ,_right(NULL)    {}};template<class K,class V>class AVLTree{    typedef AVLTreeNode<K, V> Node;public:    AVLTree()        :_root(NULL)    {}    bool Insert(const K key,const V value)    {        Node * cur = _root;        Node * parent = NULL;        if (cur == NULL)//_root为空/空树        {            _root = new Node(key, value);            _root->_bf = 0;            _root->_parent = NULL;            return true;        }        while (cur)//找插入节点位置节        {            if (cur->_key < key)            {                parent = cur;                cur = cur->_right;            }            else if (cur->_key > key)            {                parent = cur;                cur = cur->_left;            }            else//key值已存在,更新该key值得value            {                cur->_value = value;                return true;            }        }        //插入节点        Node * node = new Node(key, value);        if (parent->_key > key)        {            parent->_left = node;            node->_parent = parent;            node->_bf = 0;        }        else        {            parent->_right = node;            node->_parent = parent;            node->_bf = 0;        }        //更新平衡因子        cur = node;        while (parent)        {            if (parent->_left == cur)            {                parent->_bf--;            }            else if(parent->_right==cur)            {                parent->_bf++;            }            //根据平衡因子判断是否需要再调整祖先节点的平衡因子或调整树            if (parent->_bf == 0)            {                break;            }            else if (parent->_bf == 1 || parent->_bf == -1)            {                cur = parent;                parent = cur->_parent;            }            //如果不满足AVL树的性质,则旋转调整            else if (parent->_bf == -2)            {                if (parent->_left->_bf == -1)                {                    RotateR(parent->_left);//向右单旋                }                else if(parent->_left->_bf ==1)                {                    RotateLR(parent->_left);//左右双旋(先左单旋再向右单旋)                }                else                {                    printf("平衡因子异常\n");                    return false;                }            }            else if (parent->_bf == 2)            {                if (parent->_right->_bf == 1)                {                    RotateL(parent->_right);//向左单旋                }                else if(parent->_right->_bf==-1)                {                    RotateRL(parent->_right);//右左双旋(先右单旋,再左单旋)                }                else                {                    printf("平衡因子异常\n");                    return false;                }            }            else            {                printf("平衡因子异常\n");                return false;            }        }    }    int Height()//求二叉树的高度    {        return _Height(_root);    }    int Height(Node * root)    {        return _Height(root);    }    bool IsBlance()//判断一棵二叉树是否是平衡二叉树    {        return _IsBlance(_root);    }    void InOrder()//中序遍历树    {        _InOrder(_root);        cout << endl;    }protected:    void RotateL(Node * root)//向左单旋    {        Node *parent = root->_parent;        Node *subL = root->_left;        parent->_right = subL;        if (subL)        {            subL->_parent = parent;        }        if (parent == _root)        {            _root = root;            root->_parent = NULL;        }        else        {            if (parent->_parent->_left == parent)            {                parent->_parent->_left = root;            }            else            {                parent->_parent->_right = root;            }            root->_parent = parent->_parent;        }        root->_left = parent;        parent->_parent = root;        if (subL)        {            subL->_bf = 0;        }        parent->_bf = root->_bf = 0;    }    void RotateR(Node * root)//向右单旋    {        Node * parent = root->_parent;        Node * subR = root->_right;        parent->_left = subR;        if (subR)        {            subR->_parent = parent;        }        if (parent == _root)        {            _root = root;            root->_parent = NULL;        }        else        {            root->_parent = parent->_parent;            if (parent->_parent->_left == parent)            {                parent->_parent->_left = root;            }            else            {                parent->_parent->_right = root;            }        }        root->_right = parent;        parent->_parent = root;        if (subR)        {            subR->_bf = 0;        }        root->_bf = parent->_bf = 0;    }    void RotateLR(Node * root)//左右双旋    {        RotateL(root->_right);        RotateR(root->_parent);        Node* cur = root->_parent;        if (cur->_bf == 0)        {            cur->_left->_bf = 0;            cur->_right->_bf = 0;        }        else if(cur->_bf == 1)        {            cur->_bf = 0;            cur->_left->_bf = -1;            cur->_right->_bf = 0;        }        else if (cur->_bf == -1)        {            cur->_bf = 0;            cur->_left->_bf = 0;            cur->_right->_bf = 1;        }        else        {            printf("平衡因子异常\n");            return;        }    }    void RotateRL(Node*root)    {        RotateR(root->_left);         RotateL(root->_parent);        Node* cur = root->_parent;        if (cur->_bf == 0)        {            cur->_left->_bf = 0;            cur->_right->_bf = 0;        }        else if (cur->_bf == 1)        {            cur->_bf = 0;            cur->_left->_bf = -1;            cur->_right->_bf = 0;        }        else if (cur->_bf == -1)        {            cur->_bf = 0;            cur->_left->_bf = 0;            cur->_right->_bf = 1;        }        else        {            printf("平衡因子异常\n");            return;        }    }    int _Height(Node * root)    {        if (root == NULL)        {            return 0;        }        int left = _Height(root->_left) + 1;        int right = _Height(root->_right) + 1;        return left > right ? left : right;    }    bool _IsBlance(Node * root)    {        if (root == NULL)        {            return true;        }        int left = Height(root->_left);        int right = Height(root->_right);        if (abs(right - left) != abs(root->_bf))        {            cout << "平衡因子错误\n" << endl;            return false;        }        return (abs(right - left) < 2) && _IsBlance(root->_left) && _IsBlance(root->_right);    }    void _InOrder(Node * root)    {        if (root == NULL)        {            return;        }        _InOrder(root->_left);        cout << "key:" << root->_key << "value:" << root->_value<<" ";        _InOrder(root->_right);    }private:    Node * _root;};
阅读全文
0 0
原创粉丝点击