目录
前言
搜索二叉树
搜索二叉树 又称 二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树:
- 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值
- 若它的右子树不为空,则右子树上所有节点的值都大于根节点的值
- 它的左右子树也分别为二叉搜索树
示例:

具体可以查看搜索二叉树
但是二叉搜索树有其自身的缺陷,假如往树中插入的元素有序或者接近有序,二叉搜索树就会退化成单支树(或接近单只树),二叉搜索树的性能就失去了,并且
时间复杂度会退化成O(N),因此需要对底层结构进行平衡处理,即采用平衡树(AVL树、红黑树)来实现,使二叉搜索树的性能都能达到最优.

AVL树
AVL树的概念
二叉搜索树虽可以缩短查找的效率,但如果数据有序或接近有序二叉搜索树将退化为单支树,查
找元素相当于在顺序表中搜索元素,效率低下
。因此,两位俄罗斯的数学家
G.M.Adelson-Velskii和E.M.Landis
在
1962
年发明了一种解决上述问题的方法:当向二叉搜索树中插入新结点后,如果能保证每个结点的左右
子树高度之差的绝对值不超过
1(
需要对树中的结点进行调整
)
,即可降低树的高度,从而减少平均搜索长度。
一棵
AVL
树或者是空树,或者是具有以下性质的二叉搜索树:
- 它的左右子树都是AVL树
- 左右子树高度之差(简称平衡因子)的绝对值不超过1(-1/0/1) --- 一般是右子树减去左子树等于根

如果一棵二叉搜索树是高度平衡的,它就是
AVL
树。如果它有
n
个结点,其高度可保持在
$O(log_2 n)$
,搜索时间复杂度
O($log_2 n$)
。
AVL树节点的定义
template<class K, class V>
class AVLTreeNode
{
AVLTreeNode<K,V>* _left; //左子树节点
AVLTreeNode<K, V>* _right; //右子树节点
AVLTreeNode<K, V>* _parent; //父节点
pair<K, V> _kv;
int _bf; //balance factor :平衡因子
AVLTreeNode(const pair<K, V>& kv)
:_left(nullptr)
, _right(nullptr)
, _parent(nullptr)
,_kv(kv)
,_bf(0)
{}
};
AVL树的插入
AVL
树就是在二叉搜索树的基础上引入了平衡因子,因此
AVL
树也可以看成是二叉搜索树。那么AVL树的插入过程可以分为两步:
- 按照二叉搜索树的方式插入新节点
- 调整节点的平衡因子
template<class K,class V>
class AVLTree
{
typedef AVLTreeNode<K, V> Node;
public:
bool insert(const pair<K, V>& kv)
{
//_root为空
if (_root == nullptr)
{
_root = new Node(kv);
return true;
}
//_root不为空
Node* cur = _root;
Node* parent = nullptr; //记录cur的父节点,方便进行链接
while (cur)
{
if (kv.first < cur->_kv.first) //插入的值小于存储的值
{
parent = cur;
cur = cur->_left;
}
else if(kv.first > cur->_kv.first) //插入的值大于存储的值
{
parent = cur;
cur = cur->_right;
}
else
{
return false; //相等,则插入失败
}
}
//当前位置为空

最低0.47元/天 解锁文章
2749

被折叠的 条评论
为什么被折叠?



