C++?AVL樹的兩單旋和兩雙旋的項(xiàng)目實(shí)踐
如果在一棵原本是平衡的AVL樹中插入一個(gè)新節(jié)點(diǎn),可能造成不平衡,此時(shí)必須調(diào)整樹的結(jié)構(gòu),使之平衡化。根據(jù)節(jié)點(diǎn)插入位置的不同,AVL樹的旋轉(zhuǎn)分為四種。
1. 新節(jié)點(diǎn)插入較高左子樹的左側(cè)---左左:右單旋
a/b/c分別是高度為h的AVL子樹
上圖在插入前,AVL樹是平衡的,新節(jié)點(diǎn)插入到30的左子樹(注意:此處不是左孩子)中,30左子樹增加了一層,導(dǎo)致以60為根的二叉樹不平衡,要讓60平衡,只能將60左子樹的高度減少一層,右子樹增加一層,即將左子樹往上提,這樣60轉(zhuǎn)下來,因?yàn)?0比30大,只能將其放在30的右子樹,而如果30有右子樹,右子樹根的值一定大于30,小于60,只能將其放在60的左子樹,旋轉(zhuǎn)完成后,更新節(jié)點(diǎn)的平衡因子即可。在旋轉(zhuǎn)過程中,有以下幾種情況需要考慮:
1. 30節(jié)點(diǎn)的右孩子可能存在,也可能不存在
2. 60可能是根節(jié)點(diǎn),也可能是子樹
如果是根節(jié)點(diǎn),旋轉(zhuǎn)完成后,要更新根節(jié)點(diǎn)
如果是子樹,可能是某個(gè)節(jié)點(diǎn)的左子樹,也可能是右子樹
代碼
//右單旋 void RotateR(Node* parent) { Node* SubL = parent->_left; Node* subLR = subL->_right; parent->_left = subLR; if (subLR) { subL->_right = parent; } subL->_right = parent; Node* ppnode = parent->_parent; parent->_parent = subL; if (parent == _root) { _root = subL; subL->_parent = nullptr; } else { if (ppnode->_left == parent) { ppnode->_left = subL; } else { ppnode->_right = subL; } subL->_parent = ppnode; } parent->_bf = 0; subL->_bf = 0; }
2. 新節(jié)點(diǎn)插入較高右子樹的右側(cè)---右右:左單旋
左單旋與右單旋的操作類似,只有左右節(jié)點(diǎn)的區(qū)別
代碼
//左單旋 void RotateL(Node* parent) { Node* SubR = parent->_right; Node* subRL = subR->_left; parent->_right = subRL; if (subRL) { subR->_left = parent; } subR->_left = parent; Node* ppnode = parent->_parent; parent->_parent = subR; if (parent == _root) { _root = subR; subR->_parent = nullptr; } else { if (ppnode->_left == parent) { ppnode->_left = subR; } else { ppnode->_right = subR; } subR->_parent = ppnode; } parent->_bf = 0; subR->_bf = 0; }
3. 新節(jié)點(diǎn)插入較高左子樹的右側(cè)---左右:先左單旋再右單旋
參考30和60的相對(duì)位置,將雙旋變成單旋后再旋轉(zhuǎn),即:先對(duì)30進(jìn)行左單旋,然后再對(duì)90進(jìn)行右單旋,旋轉(zhuǎn)完成后再考慮平衡因子的更新。
代碼
//左右單旋 void RotateLR(Node* parent) { Node* subL = parent->_left; Node* subLR = subL->_right; int bf = subLR->_bf; RotateL(parent->_left); RotateR(parent); if (bf == 1) { parent->_bf = 0; subL->_bf = 0; subLR->_bf = 1; } else if (bf == -1) { parent->_bf = 0; subL->_bf = -1; subLR->_bf = 0; } else if(bf==0) { parent->_bf = 0; subL->_bf = 0; subLR->_bf = 0; } else { assert(false); } }
4. 新節(jié)點(diǎn)插入較高右子樹的左側(cè)---右左:先右單旋再左單旋
代碼
//右左單旋 void RotateRL(Node* parent) { Node* subR = parent->_right; Node* subRL = subR->_left; int bf = subRL->_bf; RotateR(parent->_right); RotateL(parent); if (bf == 1) { parent->_bf = 0; subR->_bf = 0; subRL->_bf = 1; } else if (bf == -1) { parent->_bf = 0; subR->_bf = -1; subRL->_bf = 0; } else if (bf == 0) { parent->_bf = 0; subR->_bf = 0; subRL->_bf = 0; } else { assert(false); } }
總結(jié):
假如以pParent為根的子樹不平衡,即pParent的平衡因子為2或者-2,分以下情況考慮:
1. pParent的平衡因子為2,說明pParent的右子樹高,設(shè)pParent的右子樹的根為pSubR。
當(dāng)pSubR的平衡因子為1時(shí),執(zhí)行左單旋。
當(dāng)pSubR的平衡因子為-1時(shí),執(zhí)行右左雙旋。
2. pParent的平衡因子為-2,說明pParent的左子樹高,設(shè)pParent的左子樹的根為pSubL。
當(dāng)pSubL的平衡因子為-1是,執(zhí)行右單旋。
當(dāng)pSubL的平衡因子為1時(shí),執(zhí)行左右雙旋。
旋轉(zhuǎn)完成后,原pParent為根的子樹個(gè)高度降低,已經(jīng)平衡,不需要再向上更新。
到此這篇關(guān)于C++ AVL樹的兩單旋和兩雙旋的項(xiàng)目實(shí)踐的文章就介紹到這了,更多相關(guān)C++ AVL樹內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++實(shí)現(xiàn)LeetCode(133.克隆無向圖)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(133.克隆無向圖),本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07linux根據(jù)pid獲取進(jìn)程名和獲取進(jìn)程pid(c語言獲取pid)
status文件,第一行的Name即為進(jìn)程名,C程序?qū)崿F(xiàn)根據(jù)PID獲取進(jìn)程名和根據(jù)進(jìn)程名獲取PID,大家參考使用吧2013-12-12C++ Custom Control控件向父窗體發(fā)送對(duì)應(yīng)的消息
這篇文章主要介紹了C++ Custom Control控件向父窗體發(fā)送對(duì)應(yīng)的消息的相關(guān)資料,需要的朋友可以參考下2015-06-06關(guān)于函數(shù)傳參問題(指針傳參,值傳參,引用傳參)
這篇文章主要介紹了關(guān)于函數(shù)傳參問題(指針傳參,值傳參,引用傳參),具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01C語言基于循環(huán)鏈表解決約瑟夫環(huán)問題的方法示例
這篇文章主要介紹了C語言基于循環(huán)鏈表解決約瑟夫環(huán)問題的方法,簡(jiǎn)單描述了約瑟夫環(huán)問題并結(jié)合實(shí)例形式分析了C語言使用循環(huán)鏈表解決約瑟夫環(huán)問題的具體操作技巧,需要的朋友可以參考下2018-01-01OpenCV數(shù)字圖像處理基于C++之圖像形態(tài)學(xué)處理詳解
OpenCV是一款由Intel公司俄羅斯團(tuán)隊(duì)發(fā)起并參與和維護(hù)的一個(gè)計(jì)算機(jī)視覺處理開源軟件庫(kù),支持與計(jì)算機(jī)視覺和機(jī)器學(xué)習(xí)相關(guān)的眾多算法,下面這篇文章主要給大家介紹了關(guān)于OpenCV數(shù)字圖像處理基于C++之圖像形態(tài)學(xué)處理的相關(guān)資料,需要的朋友可以參考下2022-12-12