国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【C++】AVL樹(shù)(高度平衡二叉樹(shù))

這篇具有很好參考價(jià)值的文章主要介紹了【C++】AVL樹(shù)(高度平衡二叉樹(shù))。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

概念

二叉搜索樹(shù)雖然可以縮短查找的效率,但如果數(shù)據(jù)有序或者接近有序二叉搜索樹(shù)將退化為單支樹(shù),查找元素相當(dāng)于在順序表中搜索元素,效率低下。
。因此,兩位俄羅斯的數(shù)學(xué)家G.M.Adelson-Velskii和E.M.Landis在1962年發(fā)明了一種解決上述問(wèn)題的方法:當(dāng)向二叉搜索樹(shù)中插入新結(jié)點(diǎn)后,如果能保證每個(gè)結(jié)點(diǎn)的左右子樹(shù)高度之差的絕對(duì)值不超過(guò)1(需要對(duì)樹(shù)中的結(jié)點(diǎn)進(jìn)行調(diào)整),即可降低樹(shù)的高度,從而減少平均搜索長(zhǎng)度。

AVL樹(shù)的特點(diǎn):
它的左右子樹(shù)都是AVL樹(shù)
左右子樹(shù)高度之差(簡(jiǎn)稱(chēng)平衡因子)的絕對(duì)值不超過(guò)1(-1/0/1)
如果一棵二叉搜索樹(shù)是高度平衡的,它就是AVL樹(shù)。如果它有n個(gè)結(jié)點(diǎn),其高度可保持在
O ( l o g 2 n ) O(log_2 n) O(log2?n),搜索時(shí)間復(fù)雜度O( l o g 2 n log_2 n log2?n)。

【C++】AVL樹(shù)(高度平衡二叉樹(shù)),c++,c++,開(kāi)發(fā)語(yǔ)言

AVL樹(shù)節(jié)點(diǎn)定義

template<class K,class V>
struct AVLTreeNode
{
	AVLTreeNode<K, V>* _left;// 該節(jié)點(diǎn)的左孩子
	AVLTreeNode<K, V>* _right;// 該節(jié)點(diǎn)的右孩子
	AVLTreeNode<K, V>* _parent;// 該節(jié)點(diǎn)的父節(jié)點(diǎn)

	pair<K, V> _kv;// 該節(jié)點(diǎn)的平衡因子
	int _bf;

	AVLTreeNode(const pair<K,V>& kv)
		:_left(nullptr)
		,_right(nullptr)
		,_parent(nullptr)
		,_kv(kv)
		,_bf(0)
	{}
};

AVL樹(shù)節(jié)點(diǎn)插入

AVL樹(shù)就是在二叉搜索樹(shù)的基礎(chǔ)上引入了平衡因子,因此AVL樹(shù)也可以看成是二叉搜索樹(shù)。那么
AVL樹(shù)的插入過(guò)程可以分為兩步:
1. 按照二叉搜索樹(shù)的方式插入新節(jié)點(diǎn)
2. 調(diào)整節(jié)點(diǎn)的平衡因子

【C++】AVL樹(shù)(高度平衡二叉樹(shù)),c++,c++,開(kāi)發(fā)語(yǔ)言

更新平衡因子的規(guī)則:
1、新增在右,parent->bf++; 新增在左,parent->bf–:
2、更新后,parent->bf == 1 r -1,說(shuō)明parent插入前的平衡因子是0,說(shuō)明左右子樹(shù)高度相等,插入后有一邊高,parent高度變了,需要繼續(xù)往上更新
3、更新后,parent->bf == 0,說(shuō)明parent插入前的平衡因子是1 r -1,說(shuō)明左右子樹(shù)一邊高-邊低,插入后兩邊一樣高,插入填上了矮了那邊,parent所在子樹(shù)高度不變,不需要繼續(xù)往上更新
4更新后,parent->bf == 2 r -2,說(shuō)明parent插入前的平衡因子是1 or -1,已經(jīng)平衡臨界值,插入變成2 or -2,打破平衡,parent所在子樹(shù)需要旋轉(zhuǎn)處理。
5更新后,parent->bf > 2 r< -2的值,不可能,如果存在,則說(shuō)明插入前就不是AVL樹(shù),需要去檢查之前操作的問(wèn)題.

AVL樹(shù)四種旋轉(zhuǎn)情況
左單旋

【C++】AVL樹(shù)(高度平衡二叉樹(shù)),c++,c++,開(kāi)發(fā)語(yǔ)言

	void RotateL(Node* parent)
	{
		Node* subR = parent->_right;
		Node* subRL = subR->_left;
		parent->_right = subRL;
		if (subRL)
		{
			subRL->_parent = parent;
		}

		Node* ppNode = parent->_parent;
		subR->_left = parent;
		parent->_parent = subR;

		//1.parent是整棵樹(shù)的根
		//2.parent是子樹(shù)的根
		if (parent == _root)
		{
			_root = subR;
			subR->_parent = nullptr;
		}
		else
		{
			if (ppNode->_left == parent)
			{
				ppNode->_left = subR;
			}
			else
			{
				ppNode->_right = subR;
			}
			subR->_parent = ppNode;
		}
		subR->_bf = parent->_bf = 0;
	}
右單旋

【C++】AVL樹(shù)(高度平衡二叉樹(shù)),c++,c++,開(kāi)發(fā)語(yǔ)言

	//右單旋
	void RotateR(Node* parent)
	{
		Node* subL = parent->_left;
		Node* subLR = subL->_right;

		parent->_left = subLR;
		if (subLR)
		{
			subLR->_parent = parent;
		}

		Node* ppNode = parent->_parent;
		subL->_right = parent;
		parent->_parent = subL;

		if (ppNode == nullptr)
		{
			_root = subL;
			subL->_parent = nullptr;
		}
		else
		{
			if (ppNode->_left == parent)
			{
				ppNode->_left = subL;
			}
			else
			{
				ppNode->_right = subL;
			}
			subL->_parent = ppNode;
		}

		parent->_bf = subL->_bf = 0;
	}
先左單旋再右單旋

【C++】AVL樹(shù)(高度平衡二叉樹(shù)),c++,c++,開(kāi)發(fā)語(yǔ)言

void RotateLR(Node* parent)
	{
		Node* subL = parent->_left;
		Node* subLR = subL->_right;
		int bf = subLR->_bf;
		RotateL(parent->_left);
		RotateR(parent);

		//旋轉(zhuǎn)完后的根節(jié)點(diǎn)
		subLR->_bf = 0;
		if (bf == 1)
		{
 			subL->_bf = -1;
		}
		else if (bf == -1)
		{
			parent->_bf = 0;
			subL->_bf = 1;
		}
		else if (bf == 0)
		{
			parent->_bf = 0;
			subL->_bf = 0;
		}
		else
		{
			assert(false);
		}
	}
先右單旋后左單旋

【C++】AVL樹(shù)(高度平衡二叉樹(shù)),c++,c++,開(kāi)發(fā)語(yǔ)言文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-673906.html

	//右左雙旋
	void RotateRL(Node* parent)
	{
		Node* subR = parent->_right;
		Node* subRL = subR->_left;
		int bf = subRL->_bf;
		RotateR(parent->_right);
		RotateL(parent);
		subRL->_bf = 0;
		if (bf == 1)
		{
			subR->_bf = 0;
			parent->_bf = -1;
		}
		else if (bf == -1)
		{
			subR->_bf = 1;
			parent->_bf = 0;
		}
		else if (bf == 0)
		{
			subR->_bf = 0;
			parent->_bf = 0;
		}
		else
		{
			assert(false);
		}
	}

元素的插入及控制平衡

typedef AVLTreeNode<K, V> Node;
	bool Insert(const pair<K, V>& kv)
	{
		//如果當(dāng)前樹(shù)為空直接設(shè)置節(jié)點(diǎn)
		if (_root == NULL)
		{
			_root = new Node(kv);
			return true;
		}
		//需要有指針記錄上一個(gè)移動(dòng)位置
		Node* cur = _root;
		Node* parent = nullptr;
		//尋找合適位置插入
		while (cur)
		{
			if (cur->_kv.first < kv.first)
			{
				parent = cur;
				cur = cur->_right;
			}
			else if (cur->_kv.first > kv.first)
			{
				parent = cur;
				cur = cur->_left;
			}
			else
			{
				return false;
			}
		}
		//直接插入節(jié)點(diǎn)并設(shè)置它的指向
		cur = new Node(kv);
		if (parent->_kv.first < kv.first)
		{
			parent->_right = cur;
		}
		else
		{
			parent->_left = cur;
		}
		cur->_parent = parent;
		//控制平衡
		//1.更新平衡因子
		while (parent)
		{
			if (parent->_right == cur)
			{
				parent->_bf++;
			}
			else
			{
				parent->_bf--;
			}

			if (parent->_bf == 0)
			{
				break;
			}
			else if (abs(parent->_bf) == 1)
			{	//如果為1整體向上移動(dòng)再次調(diào)增平衡
				parent = parent->_parent;
				cur = cur->_parent;
			}
			else if (abs(parent->_bf) == 2)
			{
				//說(shuō)明parent所在子樹(shù)已經(jīng)不平衡了,需要旋轉(zhuǎn)處理
				if (parent->_bf == 2 && cur->_bf == 1)
				{
					RotateL(parent);
				}
				else if (parent->_bf == -2 && cur->_bf == -1)
				{
					RotateR(parent);
				}
				else if (parent->_bf == -2 && cur->_bf == 1)
				{
					RotateLR(parent);
				}
				else if (parent->_bf == 2 && cur->_bf == -1)
				{
					RotateRL(parent);
				}
				else
				{
					//預(yù)防調(diào)整出錯(cuò)情況
					assert(false);
				}
				break;
			}
			else
			{
			//預(yù)防調(diào)整出錯(cuò)情況
				assert(false);
			}
		}
		return true;

	}

判斷最后節(jié)點(diǎn)是否平衡

	//判斷是否平衡
bool _IsBanlance(Node* root)
	{
		if (root == NULL)
		{
			return true;
		}

		int leftH = _Height(root->_left);
		int rightH = _Height(root->_right);

		if (rightH - leftH != root->_bf)
		{
			cout << root->_kv.first << "節(jié)點(diǎn)平衡因子異常" << endl;
			return false;
		}

		return abs(leftH - rightH) < 2
			&& _IsBanlance(root->_left)
			&& _IsBanlance(root->_right);
	}

	//計(jì)算它的最大高度
	int _Height(Node* root)
	{
		if (root == nullptr)
		{
			return 0;
		}

		int leftH = _Height(root->_left);
		int rightH = _Height(root->_right);

		return max(leftH, rightH) + 1;
	}

到了這里,關(guān)于【C++】AVL樹(shù)(高度平衡二叉樹(shù))的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 數(shù)據(jù)結(jié)構(gòu)和算法學(xué)習(xí)記錄——平衡二叉樹(shù)(基本介紹、平衡因子、平衡二叉樹(shù)的定義、平衡二叉樹(shù)的高度)

    數(shù)據(jù)結(jié)構(gòu)和算法學(xué)習(xí)記錄——平衡二叉樹(shù)(基本介紹、平衡因子、平衡二叉樹(shù)的定義、平衡二叉樹(shù)的高度)

    目錄 基本介紹 平衡因子 平衡二叉樹(shù)? 平衡二叉樹(shù)的高度? 什么是平衡二叉樹(shù)? 以一個(gè)例子來(lái)解釋一下: 搜索樹(shù)結(jié)點(diǎn)按不同的插入次序,將會(huì)導(dǎo)致不同的深度和平均查找長(zhǎng)度ASL ? 在二叉搜索樹(shù)中查找一個(gè)元素:? (a)要找到Jan,需要查找一次;要找到Feb,需要查找兩次;

    2023年04月26日
    瀏覽(40)
  • 【樹(shù)】 二叉樹(shù) 堆與堆排序 平衡(AVL)樹(shù) 紅黑(RB)樹(shù)

    【樹(shù)】 二叉樹(shù) 堆與堆排序 平衡(AVL)樹(shù) 紅黑(RB)樹(shù)

    樹(shù)是一種非線性的數(shù)據(jù)結(jié)構(gòu),它是由n(n=0)個(gè)有限結(jié)點(diǎn)組成一個(gè)具有層次關(guān)系的集合。 有一個(gè)特殊的結(jié)點(diǎn),稱(chēng)為根結(jié)點(diǎn),根節(jié)點(diǎn)沒(méi)有前驅(qū)結(jié)點(diǎn) 除根節(jié)點(diǎn)外,其余結(jié)點(diǎn)被分成M(M0)個(gè)互不相交的集合T1、T2、……、Tm,其中每一個(gè)集合Ti(1= i= m)又是一棵結(jié)構(gòu)與樹(shù)類(lèi)似的子樹(shù)。每棵子

    2024年02月14日
    瀏覽(20)
  • C/C++數(shù)據(jù)結(jié)構(gòu)(十一)—— 平衡二叉樹(shù)(AVL樹(shù))

    C/C++數(shù)據(jù)結(jié)構(gòu)(十一)—— 平衡二叉樹(shù)(AVL樹(shù))

    二叉搜索樹(shù)雖可以縮短查找的效率,但如果數(shù)據(jù)有序或接近有序二叉搜索樹(shù)將退化為單支樹(shù),查找元素相當(dāng)于在順序表中搜索元素,效率低下。 因此,兩位俄羅斯的數(shù)學(xué)家 G.M.Adelson-Velskii 和 E.M.Landis 在 1962 年發(fā)明了一種解決上述問(wèn)題的方法:當(dāng)向二叉搜索樹(shù)中插入新結(jié)點(diǎn)后,

    2024年02月02日
    瀏覽(24)
  • 計(jì)算機(jī)基礎(chǔ)--->數(shù)據(jù)結(jié)構(gòu)(6)【AVL樹(shù)(平衡二叉樹(shù))】

    計(jì)算機(jī)基礎(chǔ)--->數(shù)據(jù)結(jié)構(gòu)(6)【AVL樹(shù)(平衡二叉樹(shù))】

    平衡二叉樹(shù)是一種特殊的二叉搜索樹(shù),他的左子樹(shù)與右子樹(shù)的高度差不超過(guò)1。并且左右兩個(gè)子樹(shù)都是一顆平衡二叉樹(shù)。保持平衡的特性使得平衡二叉樹(shù)的查詢(xún)、插入和刪除操作在平均和最壞情況下的時(shí)間復(fù)雜度都是 O(logn) ,其中n是樹(shù)中節(jié)點(diǎn)的數(shù)量。 相比于普通的二叉搜索樹(shù)

    2024年02月12日
    瀏覽(20)
  • 【C++】AVL(平衡二叉搜索樹(shù))樹(shù)的原理及實(shí)現(xiàn)

    【C++】AVL(平衡二叉搜索樹(shù))樹(shù)的原理及實(shí)現(xiàn)

    文章目錄 一、引言 二、AVL樹(shù)的概念 三、AVL樹(shù)的插入 3、1?AVL樹(shù)的簡(jiǎn)單插入 3、2 旋轉(zhuǎn)分類(lèi) ?3、2、1 新節(jié)點(diǎn)插入較高右子樹(shù)的右側(cè):左單旋 3、2、2?新節(jié)點(diǎn)插入較高左子樹(shù)的左側(cè):右單旋 3、2、3?新節(jié)點(diǎn)插入較高左子樹(shù)的右側(cè):左右雙旋(先左后右) 3、2、4?新節(jié)點(diǎn)插入較高右

    2024年02月13日
    瀏覽(21)
  • 數(shù)據(jù)結(jié)構(gòu)07:查找[C++][平衡二叉排序樹(shù)AVL]

    數(shù)據(jù)結(jié)構(gòu)07:查找[C++][平衡二叉排序樹(shù)AVL]

    圖源:文心一言 考研筆記整理1w+字,小白友好、代碼可跑,請(qǐng)小伙伴放心食用~~???? 第1版:查資料、寫(xiě)B(tài)UG、畫(huà)導(dǎo)圖、畫(huà)配圖~???? 參考用書(shū): 王道考研《2024年 數(shù)據(jù)結(jié)構(gòu)考研復(fù)習(xí)指導(dǎo)》 參考用書(shū)配套視頻: 7.3_2 平衡二叉樹(shù)_嗶哩嗶哩_bilibili 特別感謝: ?Chat GPT老師、文心

    2024年02月11日
    瀏覽(46)
  • 【C++庖丁解?!孔云胶舛嫠阉鳂?shù)--AVL樹(shù)

    【C++庖丁解?!孔云胶舛嫠阉鳂?shù)--AVL樹(shù)

    ??你好,我是 RO-BERRY ?? 致力于C、C++、數(shù)據(jù)結(jié)構(gòu)、TCP/IP、數(shù)據(jù)庫(kù)等等一系列知識(shí) ??感謝你的陪伴與支持 ,故事既有了開(kāi)頭,就要畫(huà)上一個(gè)完美的句號(hào),讓我們一起加油 前面對(duì)map/multimap/set/multiset進(jìn)行了簡(jiǎn)單的介紹,在其文檔介紹中發(fā)現(xiàn),這幾個(gè)容器有個(gè)共同點(diǎn)是:其底層都

    2024年04月09日
    瀏覽(29)
  • Redis的實(shí)現(xiàn)三:c語(yǔ)言實(shí)現(xiàn)平衡二叉樹(shù),通過(guò)平衡二叉樹(shù)實(shí)現(xiàn)排序集

    Redis的實(shí)現(xiàn)三:c語(yǔ)言實(shí)現(xiàn)平衡二叉樹(shù),通過(guò)平衡二叉樹(shù)實(shí)現(xiàn)排序集

    概況 :Redis中的排序集數(shù)據(jù)結(jié)構(gòu)是相當(dāng)復(fù)雜的獨(dú)特而有用的東西。它不僅提供了順序排序數(shù)據(jù)的能力,而且具有按排名查詢(xún)有序數(shù)據(jù)的獨(dú)特特性。 (Sorted Set)是一種特殊的數(shù)據(jù)結(jié)構(gòu),它結(jié)合了集合(Set)和有序列表(List)的特點(diǎn)。在Redis中,每個(gè)成員都有一個(gè)分?jǐn)?shù)(score),

    2024年01月16日
    瀏覽(15)
  • C++數(shù)據(jù)結(jié)構(gòu)之平衡二叉搜索樹(shù)(一)——AVL的實(shí)現(xiàn)(zig與zag/左右雙旋/3+4重構(gòu))

    C++數(shù)據(jù)結(jié)構(gòu)之平衡二叉搜索樹(shù)(一)——AVL的實(shí)現(xiàn)(zig與zag/左右雙旋/3+4重構(gòu))

    本文是介紹眾多平衡二叉搜索樹(shù)(BBST)的第一篇——介紹AVL樹(shù)。故先來(lái)引入BBST的概念。由于上一篇介紹的二叉搜索樹(shù)(BST)在極度退化的情況下,十分不平衡,不平衡到只朝一側(cè)偏,成為一條鏈表,復(fù)雜度可達(dá) O ( n ) O(n) O ( n ) ,所以我們要在“平衡”方面做一些約束,以防

    2024年02月13日
    瀏覽(27)
  • 平衡二叉樹(shù)(詳細(xì)解釋+完整C語(yǔ)言)

    平衡二叉樹(shù)(詳細(xì)解釋+完整C語(yǔ)言)

    目錄 1.前言 2.什么是平衡二叉樹(shù) 2.1定義 2.2平衡因子 2.3結(jié)點(diǎn)結(jié)構(gòu) 3.插入 3.1失衡 3.2旋轉(zhuǎn) 3.3總結(jié) 3.4插入代碼 4.刪除 4.1刪除葉子結(jié)點(diǎn) 4.2刪除結(jié)點(diǎn)有左子樹(shù)或右子樹(shù) 4.3刪除結(jié)點(diǎn)有左右子樹(shù) 4.4刪除代碼 5.完整代碼 6.運(yùn)行結(jié)果 6.1LL 6.2RR 6.3LR 6.4RL ?? 在前面的學(xué)習(xí)過(guò)程中,我們了解到

    2024年02月06日
    瀏覽(15)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包