上次写了关于二叉搜索树的分析,但是二叉搜索树有一个缺陷,就是当插入一个有序(或接近有序)的序列时,二叉搜索树就相当于一个链表了,搜索效率会特别低。那么,如何来改进呢?这就引入了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;