代码:
#pragma once
#include<iostream>
using namespace std;
template<class K, class V>
struct AVLTreeNode
{
AVLTreeNode(const K& key, const V& value)
: _pLeft(NULL)
, _pRight(NULL)
, _pParent(NULL)
, _key(key)
, _value(value)
, _bf(0)
{}
AVLTreeNode<K, V> *_pLeft;
AVLTreeNode<K, V> *_pRight;
AVLTreeNode<K, V> *_pParent;
K _key;
V _value;
int _bf; // 平衡因子:right-left
};
template<class K, class V>
class AVLTree
{
typedef AVLTreeNode<K, V> Node;
public:
AVLTree()
: _pRoot(NULL)
{}
bool Insert(const K& key, const V& value)
{
if(NULL==_pRoot)
{
_pRoot=new Node(key,value);
return true;
}
//找到要插入的位置
Node* pCur=_pRoot;
Node* pParent=NULL;
while(pCur)
{
if(key<pCur->_key)
{
pParent=pCur;
pCur=pCur->_pLeft;
}
else if(key>pCur->_key)
{
pParent=pCur;
pCur=pCur->_pRight;
}
else
return false;
}
pCur=new Node(key,value);
if(key<pParent->_key)
pParent->_pLeft=pCur;
else
pParent->_pRight=pCur;
pCur->_pParent=pParent;
//已经插入,更新平衡因子,当不满足AVL时进行旋转
while(pParent)//更新到根节点
{
if(pCur==pParent->_pLeft)
pParent->_bf--;
else
pParent->_bf++;
if(0==pParent->_bf)//插入前双亲有左子树或右子树,插入后无需更新_bf
return true;
else if(1==pParent->_bf||-1==pParent->_bf)//插入前双亲为叶子结点,直接向上走
{
pCur=pParent;
pParent=pParent->_pParent;
}
else//同号单旋,异号双旋
{
if(2==pParent->_bf)
{
if(1==pCur->_bf)
_RotateLeft(pParent);
else if(-1==pCur->_bf)
_RotateRL(pParent);
}
else
{
if(-1==pCur->_bf)
_RotateRight(pParent);
else if(1==pCur->_bf)
_RotateLR(pParent);
}
break;
}
}
// return true;
}
void InOrder()
{
cout<<"InOrder: ";
_InOrder(_pRoot);
cout<<endl;
}
size_t Height()
{
return _Height(_pRoot);
}
bool IsBalanceTree()
{
return _IsBalanceTree(_pRoot);
}
private:
// 检测二叉树是否为平衡树?
bool _IsBalanceTree(Node* pRoot)
{
if(NULL==pRoot)
return true;
int LeftHeight=_Height(pRoot->_pLeft);
int RightHeight=_Height(pRoot->_pRight);
if(pRoot->_bf!=(RightHeight-LeftHeight)||abs(pRoot->_bf)>=2)
return false;
return _IsBalanceTree(pRoot->_pLeft) && _IsBalanceTree(pRoot->_pRight);
}
size_t _Height(Node* pRoot)
{
int hl=0;
int hr=0;
int max=0;
if(pRoot!=NULL)
{
hl=_Height(pRoot->_pLeft);
hr=_Height(pRoot->_pRight);
max=hl>hr?hl:hr;
return max+1;
}
else
return 0;
}
void _InOrder(Node* pRoot)
{
if(pRoot)
{
_InOrder(pRoot->_pLeft);
cout<<pRoot->_key<<" ";
_InOrder(pRoot->_pRight);
}
}
void _RotateLeft(Node* pParent)
{
Node* pSubR=pParent->_pRight;
Node* pSubRL=pSubR->_pLeft;
pParent->_pRight=pSubRL;
if(pSubRL)
pSubRL->_pParent=pParent;
pSubR->_pLeft=pParent;
Node* pPParent=pParent->_pParent;
pParent->_pParent=pSubR;
pSubR->_pParent=pPParent;
if(pPParent==NULL)
_pRoot=pSubR;
else
{
if(pPParent->_pLeft==pParent)
pPParent->_pLeft=pSubR;
else
pPParent->_pRight=pSubR;
}
pSubR->_bf=pParent->_bf=0;
}
void _RotateRight(Node* pParent)
{
Node* pSubL=pParent->_pLeft;
Node* pSubLR=pSubL->_pRight;
pParent->_pLeft=pSubLR;
if(pSubLR)
pSubLR->_pParent=pParent;
pSubL->_pRight=pParent;
Node* pPParent=pParent->_pParent;
pParent->_pParent=pSubL;
pSubL->_pParent=pPParent;
if(pPParent==NULL)
_pRoot=pSubL;
else
{
if(pPParent->_pLeft==pParent)
pPParent->_pLeft=pSubL;
else
pPParent->_pRight=pSubL;
}
pSubL->_bf=pParent->_bf=0;
}
void _RotateLR(Node* pParent)
{
Node* pSubL=pParent->_pLeft;
Node* pSubLR=pSubL->_pRight;
int bf=pSubLR->_bf;
_RotateLeft(pParent->_pLeft);
_RotateRight(pParent);
if(-1==bf)
pParent->_bf=1;
else if(1==bf)
pSubL->_bf=-1;
}
void _RotateRL(Node* pParent)
{
Node* pSubR=pParent->_pRight;
Node* pSubRL=pSubR->_pLeft;
int bf=pSubRL->_bf;
_RotateRight(pParent->_pRight);
_RotateLeft(pParent);
if(1==bf)
pParent->_bf=-1;
else if(-1==bf)
pSubR->_bf=1;
}
private:
Node* _pRoot;
};
void TestAVL()
{
//int array[] = {16, 3, 7, 11, 9, 26, 18, 14, 15};
int array[] = {4, 2, 6, 1, 3, 5, 15, 7, 16, 14}; AVLTree<int, int> t; for(size_t idx = 0; idx < sizeof(array)/sizeof(array[0]); ++idx) t.Insert(array[idx], idx); t.InOrder(); if(t.IsBalanceTree()) { cout<<"是AVL树"<<endl; } else { cout<<"不是AVL树"<<endl; } } int main() { TestAVL(); return 0; }