文章目录
AVL树的特点
- 二叉搜索树可以使查找的效率提升到 l o g 2 n log_2n log2n,但如果数据基本有序那么二叉搜索树会退化成单枝树,查找效率相当于在顺序表中搜索数据,效率低。两种平衡二叉搜索树解决了这个问题:AVL树和红黑树
- AVL树特点:
- 每个节点的左右子树高度差的绝对值不超过1,即降低了树的高度,从而降低平均搜索时间
- 空树也是AVL树,AVL树的每颗子树都是AVL树
- 因此AVL树每进行一次插入删除操作都要保证树的平衡
AVL插入后的四种场景
- 右单旋:插入位置:较高左子树的左侧(外侧)
- 方法:
- 将subL向上提,调整subL、subLR、parent节点的指针域
- 判断parent的父节点是否存在
- 把parent和subL的平衡因子置0
- 左右双旋:插入位置:较高左子树的右侧(内侧)
- 方法:
- 先对parent->left 进行左单旋,将问题转换成右单旋的场景
- 再对parent进行右单旋
- 通过判断subLR的初始平衡因子,调整树的平衡因子
- 若bf == -1,parent->bf = 1
- 若bf == 1,subL->bf = -1
-
左单旋:插入位置:较高右子树的右侧(外侧)
-
方法:
- 将subR向上提,调整subR、subRL、parent的指针域
- 判断parent父节点是否存在
- 把subR和parent的平衡因子置0
-
右左双旋:插入位置:较高右子树的左侧(内侧)
- 方法:
- 先对parent->left 进行右单旋,将问题转换成左单旋的场景
- 再对parent进行左单旋
- 通过判断subLR的平衡因子,调整树的平衡因子
- 若bf == -1,则subR->bf = 1
- 若bf == 1,则parent->bf = -1
- 方法:
代码实现
#pragma once
#include <iostream>
using namespace std;
template<class T>
class AVLNode
{
public:
AVLNode(const T& data = T())
:left(nullptr)
,right(nullptr)
,parent(nullptr)
,val(data)
,bf_(0)
{
}
AVLNode<T>* left;
AVLNode<T>* right;
AVLNode<T>* parent;
T val;
int bf_;
};
template<class T>
class AVLTree
{
typedef AVLNode<T> Node;
public:
AVLTree()
:root_(nullptr)
{
}
~AVLTree