AVL树
AVL树是一个高度平衡的二叉搜索树,我们知道,二叉搜索树在最理想的情况下的时间复杂度为O(logN),但在极度差的情况下(比如左右单只),二叉搜索树会退化成一个单链表,时间复杂度退化为O(n),为了保证二叉搜索树的效率控制在O(logN),对二叉树做一些改变,是的它变为极度平衡的VAL树。
AVL树的定义
一棵AVL树或者是空树,或者是左右子树都是AVL树,其中左右子树的高度之差(简称平衡因子)的绝对值不超过1
平衡化旋转
如果一棵二叉树原来是平衡的,再插入一个节点后变得不平衡(平衡因子变为2或者-2),那么就需要旋转操作来使二叉树重新平衡,有四种情况需要考虑:
左单旋
- 左旋转算法如下-以subR为轴心进行旋转
- 接下来更新平衡因子,subR和parent的平衡因子发生改变,都变为0,
右单旋
- 右单旋算法如下-以subL为轴心进行旋转
- 更新平衡因子,subL和parent的平衡因子发生改变,都变为0
先左旋后右旋
- 左右旋的算法如下
更新平衡因子,分为3种情况
- 第一种:要插入的就是subLR本身
- 第二种:节点插在subLR的右边
- 第三种:节点插在subLR的左边
- 第一种:要插入的就是subLR本身
先右旋再左旋
- 右左双旋的算法如下
- 更新平衡因子,分为3种情况
- 第一种:要插入的就是subRL本身
- 第二种:节点插在subRL的左边
- 第三种:节点插在subRL的右边
- 第一种:要插入的就是subRL本身
- 更新平衡因子,分为3种情况
代码:
#include<iostream>
#include<assert.h>
using namespace std;
template<typename K,typename V>
struct AVLtreeNode
{
K _key;
V _value;
int _bf;//平衡因子
AVLtreeNode* _pLeft;
AVLtreeNode* _pRight;
AVLtreeNode* _pParent;
AVLtreeNode(const K& key, const V& value)
:_key(key)
, _value(value)
, _bf(0)
, _pLeft(NULL)
, _pRight(NULL)
, _pParent(NULL)
{}
};
template<typename K,typename V>
class AVLTree
{
typedef AVLtreeNode<K,V> Node;
typedef Node* pNode;
public:
AVLTree()
:_pRoot(NULL)
{}
bool Find(const K& key)
{
Node* pCur = _pRoot;
while (pCur)
{
if (pCur->_key < key)
pCur = pCur->_right;
else if (pCur->_key>key)
pCur = pCur->_left;
else
return true;