欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++?AVL樹的兩單旋和兩雙旋的項目實踐

 更新時間:2024年03月20日 09:49:41   作者:敲敲er  
本文主要介紹了C++?AVL樹的兩單旋和兩雙旋的項目實踐,根據(jù)節(jié)點插入位置的不同,AVL樹的旋轉(zhuǎn)分為四種,下面就來介紹一下,感興趣的可以了解一下

如果在一棵原本是平衡的AVL樹中插入一個新節(jié)點,可能造成不平衡,此時必須調(diào)整樹的結(jié)構(gòu),使之平衡化。根據(jù)節(jié)點插入位置的不同,AVL樹的旋轉(zhuǎn)分為四種。

1. 新節(jié)點插入較高左子樹的左側(cè)---左左:右單旋

a/b/c分別是高度為h的AVL子樹

上圖在插入前,AVL樹是平衡的,新節(jié)點插入到30的左子樹(注意:此處不是左孩子)中,30左子樹增加了一層,導(dǎo)致以60為根的二叉樹不平衡,要讓60平衡,只能將60左子樹的高度減少一層,右子樹增加一層,即將左子樹往上提,這樣60轉(zhuǎn)下來,因為60比30大,只能將其放在30的右子樹,而如果30有右子樹,右子樹根的值一定大于30,小于60,只能將其放在60的左子樹,旋轉(zhuǎn)完成后,更新節(jié)點的平衡因子即可。在旋轉(zhuǎn)過程中,有以下幾種情況需要考慮:
1. 30節(jié)點的右孩子可能存在,也可能不存在
2. 60可能是根節(jié)點,也可能是子樹
如果是根節(jié)點,旋轉(zhuǎn)完成后,要更新根節(jié)點
如果是子樹,可能是某個節(jié)點的左子樹,也可能是右子樹

代碼

//右單旋
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é)點插入較高右子樹的右側(cè)---右右:左單旋

左單旋與右單旋的操作類似,只有左右節(jié)點的區(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é)點插入較高左子樹的右側(cè)---左右:先左單旋再右單旋

參考30和60的相對位置,將雙旋變成單旋后再旋轉(zhuǎn),即:先對30進行左單旋,然后再對90進行右單旋,旋轉(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é)點插入較高右子樹的左側(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時,執(zhí)行左單旋。
當(dāng)pSubR的平衡因子為-1時,執(zhí)行右左雙旋。
2. pParent的平衡因子為-2,說明pParent的左子樹高,設(shè)pParent的左子樹的根為pSubL。
當(dāng)pSubL的平衡因子為-1是,執(zhí)行右單旋。
當(dāng)pSubL的平衡因子為1時,執(zhí)行左右雙旋。
旋轉(zhuǎn)完成后,原pParent為根的子樹個高度降低,已經(jīng)平衡,不需要再向上更新。

到此這篇關(guān)于C++ AVL樹的兩單旋和兩雙旋的項目實踐的文章就介紹到這了,更多相關(guān)C++ AVL樹內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++實現(xiàn)LeetCode(133.克隆無向圖)

    C++實現(xiàn)LeetCode(133.克隆無向圖)

    這篇文章主要介紹了C++實現(xiàn)LeetCode(133.克隆無向圖),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • C++深入講解初始化列表的用法

    C++深入講解初始化列表的用法

    這篇文章主要介紹了C++成員初始化列表,除了可以使用構(gòu)造函數(shù)對類成員進行初始化之外,C++還提供了另外一種初始化的方法,叫做成員初始化列表。下面來看看文章的詳細(xì)吧,需要的朋友可以參考一下
    2022-04-04
  • 詳解C++的反調(diào)試技術(shù)與繞過手法

    詳解C++的反調(diào)試技術(shù)與繞過手法

    反調(diào)試技術(shù),惡意代碼會用它識別自身是否被調(diào)試,或者讓調(diào)試器失效,給反病毒工程師們制造麻煩,拉長提取特征碼的時間線,本章將具體總結(jié)常見的反調(diào)試基礎(chǔ)的實現(xiàn)原理以及如何過掉這些反調(diào)試手段,從而讓我們能夠繼續(xù)分析惡意代碼
    2021-06-06
  • C語言 深入淺出講解指針的使用

    C語言 深入淺出講解指針的使用

    指針是C語言中一個非常重要的概念,也是C語言的特色之一。使用指針可以對復(fù)雜數(shù)據(jù)進行處理,能對計算機的內(nèi)存分配進行控制,在函數(shù)調(diào)用中使用指針還可以返回多個值
    2022-03-03
  • linux根據(jù)pid獲取進程名和獲取進程pid(c語言獲取pid)

    linux根據(jù)pid獲取進程名和獲取進程pid(c語言獲取pid)

    status文件,第一行的Name即為進程名,C程序?qū)崿F(xiàn)根據(jù)PID獲取進程名和根據(jù)進程名獲取PID,大家參考使用吧
    2013-12-12
  • C++ Custom Control控件向父窗體發(fā)送對應(yīng)的消息

    C++ Custom Control控件向父窗體發(fā)送對應(yīng)的消息

    這篇文章主要介紹了C++ Custom Control控件向父窗體發(fā)送對應(yīng)的消息的相關(guān)資料,需要的朋友可以參考下
    2015-06-06
  • 關(guān)于函數(shù)傳參問題(指針傳參,值傳參,引用傳參)

    關(guān)于函數(shù)傳參問題(指針傳參,值傳參,引用傳參)

    這篇文章主要介紹了關(guān)于函數(shù)傳參問題(指針傳參,值傳參,引用傳參),具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • C語言基于循環(huán)鏈表解決約瑟夫環(huán)問題的方法示例

    C語言基于循環(huán)鏈表解決約瑟夫環(huán)問題的方法示例

    這篇文章主要介紹了C語言基于循環(huán)鏈表解決約瑟夫環(huán)問題的方法,簡單描述了約瑟夫環(huán)問題并結(jié)合實例形式分析了C語言使用循環(huán)鏈表解決約瑟夫環(huán)問題的具體操作技巧,需要的朋友可以參考下
    2018-01-01
  • C++ stringstream類用法詳解

    C++ stringstream類用法詳解

    這篇文章主要介紹了C++ stringstream類用法詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • OpenCV數(shù)字圖像處理基于C++之圖像形態(tài)學(xué)處理詳解

    OpenCV數(shù)字圖像處理基于C++之圖像形態(tài)學(xué)處理詳解

    OpenCV是一款由Intel公司俄羅斯團隊發(fā)起并參與和維護的一個計算機視覺處理開源軟件庫,支持與計算機視覺和機器學(xué)習(xí)相關(guān)的眾多算法,下面這篇文章主要給大家介紹了關(guān)于OpenCV數(shù)字圖像處理基于C++之圖像形態(tài)學(xué)處理的相關(guān)資料,需要的朋友可以參考下
    2022-12-12

最新評論