平衡二叉查找树插入节点操作( AVLTree ):旋转、调整平衡
AVL樹的插入
在向一棵本來高度平衡的AVL樹中插入一個新節點時,如果樹中某個結點的平衡因子的絕對值 > 1,則出現了不平衡。設新插入結點為P,從結點P到根節點的路徑上,每個結點為根的子樹的高度都可能增加1,因此在每執行一次二叉搜索樹的插入運算后,都需從新插入的結點P開始,沿該結點插入的路徑向根節點方向回溯,修改各結點的平衡因子,調整整棵樹的高度,恢復被破壞的平衡性質。
?
AVL樹插入算法:
?
新節點P的平衡因子為0,但其雙親結點Pr的平衡因子有三種情況:
?
1、結點Pr的平衡因子為0
在Pr的較矮的子樹上插入新節點,結點Pr平衡,其高度沒有增加,此時從Pr到根路徑上各結點為根的子樹的高度不變,即各結點的平衡因子不變,結束平衡化處理。
?
2、結點Pr的平衡因子的絕對值為1;
插入前Pr的平衡因子為0,插入后以Pr為根的子樹沒有失去平衡,但該子樹的高度增
加,需從該結點Pr向根節點方向回溯,繼續查看Pr的雙親結點的平衡性。
?
3、結點Pr的平衡因子的絕對值為2
新節點在較高的子樹插入,需要做平衡化處理:
若Pr = 2,說明右子樹高,設Pr的右子樹為q
當q的平衡因子為1,執行左單旋轉
?
?
?
?
當q的平衡因子為-1,執行先右后左雙旋轉
?
?
?
若Pr = -2,說明左子樹高,設Pr的左子樹為q
當q的平衡因子為-1,執行右單旋轉
?
當q的平衡因子為1,執行先左后右雙旋轉
?
具體代碼:
#include<iostream>??
using namespace std;
template<class K, class V>
struct AVLTreeNode
{
AVLTreeNode<K, V>* _pleft;
AVLTreeNode<K, V>* _pright;
AVLTreeNode<K, V>* _pParent;
K _key;
V _value;
int _bf;
AVLTreeNode(const K& key, const V& value)
:_pleft(NULL)
, _pright(NULL)
,_pParent(NULL)
, _key(key)
,_value(value)
,_bf(0)
{}
};
template<class K, class V>
class AVLTree
{
typedef AVLTreeNode<K, V> Node;
public:
AVLTree()
:_pRoot(NULL)
{}
AVLTree(const AVLTree<K, V>& t);
AVLTree<K, V>& operator=(const AVLTree<K, V>& t);
~AVLTree()
{
_Destory(_pRoot);
}
public:
bool Insert(const K& key, const V& value)
{
if(NULL == _pRoot)
{
_pRoot = new Node(key, value);
return true;
}
//尋找插入位置
Node* parent = NULL;
Node* pCur = _pRoot;
while(pCur)
{
if(key < pCur->_key)
{
parent = pCur;
pCur = pCur->_pleft;
}
else if(key > pCur->_key)
{
parent = pCur;
pCur = pCur->_pright;
}
else
return false;
}
pCur = new Node(key, value);
//插入
if(key < parent->_key)
{
parent->_pleft = pCur;
}
else
{
parent->_pright = pCur;
}
pCur->_pParent = parent;
//更新平衡因子
while(parent)
{
if(parent->_pleft == pCur)
{
parent->_bf--;
}
else
{
parent->_bf++;
}
if(parent->_bf == 0)
{
break;
}
else if(1 == parent->_bf || parent->_bf == -1)
{
pCur = parent;
parent = pCur->_pParent;
}
else
{
if(parent->_bf == 2)
{
if(pCur->_bf == 1)
_RotateL(parent);
else if(pCur->_bf == -1)
_RotateRL(parent);
}
else if(parent->_bf == -2)
{
if(pCur->_bf == -1)
_RotateR(parent);
else if(pCur->_bf == 1)
_RotateLR(parent);
}
break;
}
}
return true;
}
void Inorder() ? ? //中序遍歷
{
_Inorder(_pRoot);
cout << endl;
}
bool IsBalance() ? ?//判斷是否平衡
{
int height = 0;
return _IsBalance(_pRoot, height);
}
private:
void _RotateR(Node* parent)
{
Node* subL = parent->_pleft;
Node* subLR = subL->_pright;
parent->_pleft = subLR;
if(subLR)
subLR->_pParent = parent;
subL->_pright = parent;
Node* pParent = parent->_pParent;
parent->_pParent = subL;
if(pParent == NULL)
{
_pRoot = subL;
subL->_pParent = NULL;
}
else
{
if(pParent->_pleft == parent)
{
pParent->_pleft = subL;
}
else
{
pParent->_pright = subL;
}
subL->_pParent = pParent;
}
subL->_bf = parent->_bf = 0;
}
void _RotateL(Node* parent)
{
Node* subR = parent->_pright;
Node* subRL = subR->_pleft;
parent->_pright = subRL;
if(subRL)
subRL->_pParent = parent;
subR->_pleft = parent;
Node* pParent = parent->_pParent;
parent->_pParent = subR;
if(pParent == NULL)
{
_pRoot = subR;
subR->_pParent = NULL;
}
else
{
if(pParent->_pleft == parent)
{
pParent->_pleft = subR;
}
else
{
pParent->_pright = subR;
}
subR->_pParent = pParent;
}
subR->_bf = parent->_bf = 0;
}
void _RotateRL(Node*& parent)
{
? ? ? ? Node* subR = parent->_pright; ?
? ? ? ? Node* subRL = subR->_pleft; ?
? ? ? ? _RotateR(subR); ? ? ?
? ? ? ? _RotateL(parent); ? ? ??
??
? ? ? ? int bf = subRL->_bf; ?
??
? ? ? ? if (bf == 0) ?
? ? ? ? { ? ?
? ? ? ? ? ? subRL->_bf = parent->_bf = subR->_bf = 0;?
? ? ? ? } ?
??
? ? ? ? else if (bf == -1) ?
? ? ? ? { ?
? ? ? ? ? ? subRL->_bf = 0; ?
? ? ? ? ? ? parent->_bf = 1; ?
? ? ? ? ? ? subR->_bf = 0; ?
? ? ? ? } ?
??
? ? ? ? else if (bf == 1) ?
? ? ? ? { ?
? ? ? ? ? ? subRL->_bf = 0; ?
? ? ? ? ? ? parent->_bf = 0; ?
? ? ? ? ? ? subR->_bf = 1; ?
? ? ? ? }?
}
void _RotateLR(Node*& parent)
{
? ? ? ? Node* subL = parent->_pleft; ?
? ? ? ? Node* subLR = subL->_pright; ?
? ? ? ? _RotateL(subL); ?
? ? ? ? _RotateR(parent); ?
? ? ? ? int bf = subLR->_bf; ?
??
? ? ? ? if (bf == 0) ?
? ? ? ? { ?
? ? ? ? ? ? subLR->_bf = parent->_bf = subL->_bf = 0; ?
? ? ? ? } ?
??
? ? ? ? else if (bf == 1) ?
? ? ? ? { ?
? ? ? ? ? ? subLR->_bf = 0; ?
? ? ? ? ? ? parent->_bf = 1; ?
? ? ? ? ? ? subL->_bf = 0; ?
? ? ? ? } ?
??
? ? ? ? else if (bf == -1) ?
? ? ? ? { ?
? ? ? ? ? ? subLR->_bf = 0; ?
? ? ? ? ? ? parent->_bf = 0; ?
? ? ? ? ? ? subL->_bf = -1; ?
? ? ? ? } ?
}
void _Destory(Node*& pRoot)
{
if (_pRoot == NULL)
return;
_Destory(pRoot->_pleft);
_Destory(pRoot->_pright);
delete pRoot;
pRoot = NULL;
}
protected:
void _Inorder(Node* pRoot) ? ? //中序
{
if (pRoot == NULL)
{
return;
}
_Inorder(pRoot->_pleft);
cout << pRoot->_key << " ";
_Inorder(pRoot->_pright);
}
bool _IsBalance(Node* pRoot, int& height)
{
if (pRoot == NULL)
{
height = 0;
return true;
}
int left, right;
if (_IsBalance(pRoot->_pleft, left) && _IsBalance
(pRoot->_pright, right)
&& abs(right - left) < 2)
{
height = left > right ? left + 1 : right + 1;
if (pRoot->_bf != right - left)
{
cout << "平衡因子異常:" << pRoot->_key?
<< endl;
return false;
}
return true;
}
else
{
return false;
}
}
size_t _Height(Node* pRoot) ? ?//高度
{
if (pRoot == NULL)
{
return 0;
}
int l = _Height(pRoot->_pleft);
int r = _Height(pRoot->_pright);
return l > r ? l + 1 : r + 1;
}
private:
Node* _pRoot;
};
int main()
{
AVLTree<int, int> t;
t.Insert(3,3);
t.Insert(7,7);
t.Insert(11,11);
t.Insert(14,14);
t.Insert(15,15);
t.Insert(18,18);
t.Insert(16,16);
t.Insert(26,26);
t.Insert(9,9);
t.Inorder(); ?
? ? cout << "IsBalance? " << t.IsBalance() << endl; ?
system("pause");
return 0;
}
總結
以上是生活随笔為你收集整理的平衡二叉查找树插入节点操作( AVLTree ):旋转、调整平衡的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 七号信令:信令网基本概念
- 下一篇: 2021年12月最新大数据白皮书(附下载