日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

平衡二叉查找树插入节点操作( AVLTree ):旋转、调整平衡

發布時間:2023/12/20 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 平衡二叉查找树插入节点操作( 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 ):旋转、调整平衡的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。