您的位置:首页 > 职场人生

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

2017-06-24 22:57 519 查看
上次写了关于二叉搜索树的分析,但是二叉搜索树有一个缺陷,就是当插入一个有序(或接近有序)的序列时,二叉搜索树就相当于一个链表了,搜索效率会特别低。那么,如何来改进呢?这就引入了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;
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息