先声明一下这里为什么只写了AVL树节点的插入哈
好了,来主要说插入吧!
插入当中主要涉及到两个比较重要的点,一个是旋转还有一个就是平衡因子,而我们的旋转还有平衡因子为什么要改变,都是通过插入元素间接引起的。
AVL树还是主要要看图的不看图,几下子就晕了。
我们先简单的看一下这张图,主要先看一下插入节点对平衡因子的影响,黑色圈子是我插入的节点插入节点以后我们数根节点左边的高度,开始是-3,插入以后变成了-4,根节点右边一直是2,插入以后根节点平衡因子变成了-2。而追根问底从下往上寻找第一个-2产生位置在根节点左子树位置
其实我个人感觉记住低一个产生不满足条件的平衡因子是会让理解旋转很多变的方便很多的。
好了,看一下代码吧。
#include
using namespace std;
template
struct AVLTreeNode
{
AVLTreeNode(const K& key = K(), const V& value = V())
: _pLeft(nullptr)
, _pRight(nullptr)
, _pParent(nullptr)
, _key(key)
, _value(value)
, _bf(0)
{}
AVLTreeNode* _pLeft;
AVLTreeNode* _pRight;
AVLTreeNode* _pParent;
K _key;
V _value;
int _bf; // 平衡因子
};
我们主要通过在AVL树里面放了一个数值,即键值对。
bool Insert(const K& key, const V& value)
{
if (nullptr == _pRoot)
{
_pRoot = new Node(key, value);
return true;
}
// 找待插入节点的位置
PNode pCur = _pRoot;
PNode pParent = nullptr;
while (pCur)
{
pParent = pCur;
if (key < pCur->_key)
pCur = pCur->_pLeft;
else if (key > pCur->_key)
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;
while (pParent)
{
// 更新双亲的平衡因子
if (pParent->_pLeft == pCur)
pParent->_bf--;
else
pParent->_bf++;
if (0 == pParent->_bf)
break;
else if (-1 == pParent->_bf || 1 == pParent->_bf)
{
pCur = pParent;
pParent = pCur->_pParent;
}
else
{
// parent的平衡因子已经不满足情况
if (2 == pParent->_bf)
{
// 右子树比较高
if (1 == pCur->_bf)
RotateL(pParent);
else
RotateRL(pParent);
}
else
{
// 左子树比较高
if (-1 == pCur->_bf)
RotateR(pParent);
else
RotateLR(pParent);
}
break;
}
}
return true;
}
插入数值还是类比搜索二叉树,我们先检查这个节点是不是存在,如果存在就结束掉了,剩余就是更新平衡因子,然后通过平衡因子判断是否需要旋转。平衡因子的查看其实我们是要看三代的,**插入数(第一代) 插入树根节点(第二代) 插入树根节点的根节点(第三代)**里面内嵌的旋转函数下面会分情况讨论滴。
void RotateR(PNode pParent)
{
PNode pSubL = pParent->_pLeft;
PNode pSubLR = pSubL->_pRight;
pSubL->_pRight = pParent;
pParent->_pLeft = pSubLR;
if (pSubLR)
pSubLR->_pParent = pParent;
PNode pPParent = pParent->_pParent;
pParent->_pParent = pSubL;
pSubL->_pParent = pPParent;
if (nullptr == pPParent)
_pRoot = pSubL;
else
{
if (pParent == pPParent->_pLeft)
pPParent->_pLeft = pSubL;
else
pPParent->_pRight = pSubL;
}
pSubL->_bf = pParent->_bf = 0;
}
void RotateL(PNode pParent)
{
PNode pSubR = pParent->_pRight;
PNode pSubRL = pSubR->_pLeft;
pSubR->_pLeft = pParent;
pParent->_pRight = pSubRL;
if (pSubRL)
pSubRL->_pParent = pParent;
PNode pPParent = pParent->_pParent;
pSubR->_pParent = pPParent;
pParent->_pParent = pSubR;
if (nullptr == pPParent)
_pRoot = pSubR;
else
{
if (pPParent->_pLeft == pParent)
pPParent->_pLeft = pSubR;
else
pPParent->_pRight = pSubR;
}
pParent->_bf = pSubR->_bf = 0;
}
void RotateLR(PNode pParent)
{
PNode pSubL = pParent->_pLeft;
PNode pSubLR = pSubL->_pRight;
int bf = pSubLR->_bf;
RotateL(pParent->_pLeft);
RotateR(pParent);
if (1 == bf)
pSubL->_bf = -1;
else if (-1 == bf)
pParent->_bf = 1;
}
void RotateRL(PNode pParent)
{
PNode pSubR = pParent->_pRight;
PNode pSubRL = pSubR->_pLeft;
int bf = pSubRL->_bf;
RotateR(pParent->_pRight);
RotateL(pParent);
if (1 == bf)
pParent->_bf = -1;
else if (-1 == bf)
pSubR->_bf = 1;
}
#include
using namespace std;
template
struct AVLTreeNode
{
AVLTreeNode(const K& key = K(), const V& value = V())
: _pLeft(nullptr)
, _pRight(nullptr)
, _pParent(nullptr)
, _key(key)
, _value(value)
, _bf(0)
{}
AVLTreeNode* _pLeft;
AVLTreeNode* _pRight;
AVLTreeNode* _pParent;
K _key;
V _value;
int _bf; // 平衡因子
};
template
class AVLTree
{
typedef AVLTreeNode Node;
typedef Node* PNode;
public:
AVLTree()
: _pRoot(nullptr)
{}
bool Insert(const K& key, const V& value)
{
if (nullptr == _pRoot)
{
_pRoot = new Node(key, value);
return true;
}
// 找待插入节点的位置
PNode pCur = _pRoot;
PNode pParent = nullptr;
while (pCur)
{
pParent = pCur;
if (key < pCur->_key)
pCur = pCur->_pLeft;
else if (key > pCur->_key)
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;
while (pParent)
{
// 更新双亲的平衡因子
if (pParent->_pLeft == pCur)
pParent->_bf--;
else
pParent->_bf++;
if (0 == pParent->_bf)
break;
else if (-1 == pParent->_bf || 1 == pParent->_bf)
{
pCur = pParent;
pParent = pCur->_pParent;
}
else
{
// parent的平衡因子已经不满足情况
if (2 == pParent->_bf)
{
// 右子树比较高
if (1 == pCur->_bf)
RotateL(pParent);
else
RotateRL(pParent);
}
else
{
// 左子树比较高
if (-1 == pCur->_bf)
RotateR(pParent);
else
RotateLR(pParent);
}
break;
}
}
return true;
}
void InOrder()
{
_InOrder(_pRoot);
}
bool IsBalanceTree()
{
return _IsBalanceTree(_pRoot);
}
private:
bool _IsBalanceTree(PNode pRoot)
{
if (nullptr == pRoot)
return true;
int leftHeight = _Height(pRoot->_pLeft);
int rightHeight = _Height(pRoot->_pRight);
int diff = rightHeight - leftHeight;
if (abs(diff) > 1 || diff != pRoot->_bf)
return false;
return _IsBalanceTree(pRoot->_pLeft) && _IsBalanceTree(pRoot->_pRight);
}
int _Height(PNode pRoot)
{
if (nullptr == pRoot)
return 0;
int leftHeight = _Height(pRoot->_pLeft);
int rightHeight = _Height(pRoot->_pRight);
return leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1;
}
void _InOrder(PNode pRoot)
{
if (pRoot)
{
_InOrder(pRoot->_pLeft);
cout << "<" << pRoot->_key << "," << pRoot->_value << ">" << endl;
_InOrder(pRoot->_pRight);
}
}
void RotateR(PNode pParent)
{
PNode pSubL = pParent->_pLeft;
PNode pSubLR = pSubL->_pRight;
pSubL->_pRight = pParent;
pParent->_pLeft = pSubLR;
if (pSubLR)
pSubLR->_pParent = pParent;
PNode pPParent = pParent->_pParent;
pParent->_pParent = pSubL;
pSubL->_pParent = pPParent;
if (nullptr == pPParent)
_pRoot = pSubL;
else
{
if (pParent == pPParent->_pLeft)
pPParent->_pLeft = pSubL;
else
pPParent->_pRight = pSubL;
}
pSubL->_bf = pParent->_bf = 0;
}
void RotateL(PNode pParent)
{
PNode pSubR = pParent->_pRight;
PNode pSubRL = pSubR->_pLeft;
pSubR->_pLeft = pParent;
pParent->_pRight = pSubRL;
if (pSubRL)
pSubRL->_pParent = pParent;
PNode pPParent = pParent->_pParent;
pSubR->_pParent = pPParent;
pParent->_pParent = pSubR;
if (nullptr == pPParent)
_pRoot = pSubR;
else
{
if (pPParent->_pLeft == pParent)
pPParent->_pLeft = pSubR;
else
pPParent->_pRight = pSubR;
}
pParent->_bf = pSubR->_bf = 0;
}
void RotateLR(PNode pParent)
{
PNode pSubL = pParent->_pLeft;
PNode pSubLR = pSubL->_pRight;
int bf = pSubLR->_bf;
RotateL(pParent->_pLeft);
RotateR(pParent);
if (1 == bf)
pSubL->_bf = -1;
else if (-1 == bf)
pParent->_bf = 1;
}
void RotateRL(PNode pParent)
{
PNode pSubR = pParent->_pRight;
PNode pSubRL = pSubR->_pLeft;
int bf = pSubRL->_bf;
RotateR(pParent->_pRight);
RotateL(pParent);
if (1 == bf)
pParent->_bf = -1;
else if (-1 == bf)
pSubR->_bf = 1;
}
private:
PNode _pRoot;
};
void TestAVLTree()
{
//int array[] = { 16, 3, 7, 11, 9, 26, 18, 14, 15};
int array[] = { 4, 2, 6, 1, 3, 5, 15, 7, 16, 14 };
AVLTree t;
for (auto e : array)
{
t.Insert(e, e);
}
t.InOrder();
if (t.IsBalanceTree())
{
cout << "t is AVL tree!!!" << endl;
}
else
{
cout << "t is not AVL tree!!!" << endl;
}
}
int main()
{
TestAVLTree();
return 0;
}