AVL树:即平衡二叉搜索树。平衡因子bf=右子树的高度-左子树的高度,bf为0,-1,1时,此树即平衡。AVL树的前提是该树为二叉搜索树。
中序遍历只需遍历一次,且是有序的。
以下为四种旋转的图解
左单旋(RotateL):
右单旋(RotateR):
左右双旋(RotateLR):
右左旋(RotateRL):
具体代码如下:
#define _CRT_SECURE_NO_WARNINGS
#include<stdlib.h>
#include<stdio.h>
#include<assert.h>
#include<iostream>
using namespace std;
template<class K,class V>
struct AVLNode
{
AVLNode(const K& key, const V& value)
: _pLeft(NULL)
, _pRight(NULL)
, _pParent(NULL)
, _key(key)
, _value(value)
, _bf(0)
{}
AVLNode<K, V>* _pLeft;
AVLNode<K, V>* _pRight;
AVLNode<K, V>* _pParent;
K _key;
V _value;
int _bf;//平衡因子
};
template<class K,class V>
class AVLTree
{
typedef AVLNode<K, V> Node;
public:
AVLTree()
:pRoot(NULL)
{}
//插入
bool Insert(const K& key,const V& value)
{
//树为空
if (pRoot == NULL)
{
pRoot = new Node(key, value);
return true;
}
//找插入位置
Node* pCur = pRoot;
Node* parent = NULL;
while (pCur)
{
if (pCur->_key < key)
{
parent = pCur;
pCur = pCur->_pRight;
}
else if (pCur->_key>key)
{
parent = pCur;
pCur = pCur->_pLeft;
}
else
{
return false;
}
}
//插入结点
pCur = new Node(key,value);
if (parent->_key > key)
{
parent->_pLeft = pCur;
pCur->_pParent = parent;
}
else
{
parent->_pRight = pCur;
pCur->_pParent = parent;
}
//新结点插入有可能导致AVLTree不平衡,故需更新平衡因子
while (parent)
{
if (parent->_pLeft == pCur)
{
parent->_bf--;
}
else
{
parent->_bf++;
}
if (parent->_bf == 0)
break;
else if (parent->_bf == -1 || parent->_bf == 1)
{
pCur = parent;
parent = pCur->_pParent;
}
else
{
if (parent->_bf == 2)
{
if (pCur->_bf == 1)
RotateL(parent);
else
RotateRL(parent);
}
else if (parent->_bf == -2)
{
if (pCur->_bf == -1)
RotateR(parent);
else
{
RotateLR(parent);
}
}
break;
}
}
return true;
}
//中序遍历(只遍历一次,且是有序的)
void InOrder()
{
_InOrder(pRoot);
cout << "\n" << endl;
}
//求树的高度
int Height()
{
return _Height(pRoot);
}
//判断是否为AVL树
bool IsAVLTree()
{
return _IsAVLTree(pRoot);
}
private:
//左旋
void RotateL(Node* parent)
{
Node* subR = parent->_pRight;
Node* subRL = subR->_pLeft;
subR->_pLeft = parent;
parent->_pRight = subRL;
if (subRL)
{
subRL->_pParent=parent;
}
Node* pparent = parent->_pParent;
if (pparent == NULL)
{
pRoot = subR;
subR->_pParent = NULL;
}
else
{
if (pparent->_pLeft == parent)
pparent->_pLeft = subR;
else
pparent->_pRight = subR;
subR->_pParent = pparent;
}
parent->_pParent = subR;
subR->_bf = 0;
parent->_bf = 0;
}
//右旋
void RotateR(Node* parent)
{
Node* subL = parent->_pLeft;
Node* subLR = subL->_pRight;
parent->_pLeft = subLR;
subL->_pRight = parent;
if (subLR)
{
subLR->_pParent = parent;
}
Node* pparent = parent->_pParent;
if (pparent == NULL)
{
pRoot = subL;
subL->_pParent = NULL;
}
else
{
if (pparent->_pLeft == parent)
pparent->_pLeft = subL;
else
pparent->_pRight = subL;
subL->_pParent = pparent;
}
parent->_pParent = subL;
subL->_bf = 0;
parent->_bf = 0;
}
//双旋
//左右旋
void RotateLR(Node* parent)
{
Node* subL = parent->_pLeft;
Node* subLR = subL->_pRight;
int bf = subLR->_bf;
RotateL(parent->_pLeft);
RotateR(parent);
if (bf == -1)
{
parent->_bf = 1;
subL->_bf = 0;
}
else if (bf == 1)
{
parent->_bf = 0;
subL->_bf = -1;
}
else
{
parent->_bf = 0;
subL->_bf = 0;
}
}
//右左旋
void RotateRL(Node* parent)
{
Node* subR = parent->_pRight;
Node* subRL = subR->_pLeft;
int bf = subRL->_bf;
RotateR(parent->_pRight);
RotateL(parent);
if (bf == -1)
{
parent->_bf = 0;
subR->_bf = 1;
}
else if (bf == -1)
{
parent->_bf = -1;
subR->_bf = 0;
}
else
{
parent->_bf = 0;
subR->_bf = 0;
}
}
void _InOrder(Node* Root)
{
if (Root)
{
_InOrder(Root->_pLeft);
cout << Root->_key << "->";
_InOrder(Root->_pRight);
}
}
int _Height(Node* Root)
{
if (NULL == Root)
{
return 0;
}
int leftHeight = _Height(Root->_pLeft);
int rightHeight = _Height(Root->_pRight);
return leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1;
}
bool _IsAVLTree(Node* Root)
{
int lefth = _Height(Root->_pLeft);
int righth = _Height(Root->_pRight);
int bf = righth - lefth;
if (abs(bf) > 2)
return false;
return true;
}
private:
Node* pRoot;
};
void test()
{
AVLTree<int, int> avl;
avl.Insert(5, 5);
avl.Insert(2, 2);
avl.Insert(1, 1);
avl.Insert(3, 3);
avl.Insert(4, 4);
avl.Insert(0, 0);
avl.Insert(7, 7);
avl.Insert(8, 8);
avl.Insert(6, 6);
//avl.InOrder();
//cout << avl.Height() << endl;
//cout<<avl.IsAVLTree()<<endl;
}
int main()
{
test();
system("pause");
return 0;
}