【C++】红黑树
创始人
2024-11-05 19:36:39
0

红黑树 

目录

a. 红黑树的概念

b. 红黑树的性质

c. 红黑树的实现


a. 红黑树的概念

红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或

Black。 通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路

径会比其他路径长出俩倍,因而是接近平衡的

b. 红黑树的性质

  1. 每个结点不是红色就是黑色
  2. 根节点是黑色的
  3. 如果一个节点是红色的,则它的两个孩子结点是黑色的
  4. 对于每个结点,从该结点到其所有后代叶结点的简单路径上,均包含相同数目的黑色结点
  5. 空结点都是黑色的

c. 红黑树的实现

(一)红黑树节点的构建

代码

	enum Colour { 	RED, 	BLACK };  template struct RBTreeNode { 	RBTreeNode* _left; 	RBTreeNode* _right; 	RBTreeNode* _parent; 	pair _kv; 	Colour _col;  	RBTreeNode(const pair& kv) 		:_left(nullptr) 		, _right(nullptr) 		, _parent(nullptr) 		, _kv(kv) 		, _col(RED)  //默认为红节点,对于性质四,黑节点数不好控制,先默认红节点,后期再变颜色 	{} };

(二)红黑树的插入

实现思路

如果插入的是第一个节点(即根节点),由于性质二,我们需要把它变成黑色

除了上述情况,还有一种可能需要变色(回到性质三)

如图:

而面对这种情况,也分不同的做法

对于第一种情况(左图):

做法是把 parent 变成黑色的 , grandparent 变成红色的 ,uncle 变成黑色的 ,

然后 cur = grandparent , parent = cur->_parent , grandparent = parent->_parent ,uncle 也有变节点 ,直到不满足两个红节点连在一起的前提 或者 是 parent 为空(循环结束的条件)

注意:

根节点的颜色可能会在过程中更改(如上述右图),一定要在最后改回成黑色

对于第二种情况:

parent 变成黑色 , grandparent 变成红色 ,再发生旋转(跟 AVL树 的旋转情况一样),完成 break即可

 

 代码

	enum Colour { 	RED, 	BLACK };  template struct RBTreeNode { 	RBTreeNode* _left; 	RBTreeNode* _right; 	RBTreeNode* _parent; 	pair _kv; 	Colour _col;  	RBTreeNode(const pair& kv) 		:_left(nullptr) 		, _right(nullptr) 		, _parent(nullptr) 		, _kv(kv) 		, _col(RED) 	{} };   template class RBTree { 	typedef RBTreeNode Node; public: 	bool Insert(const pair& kv) 	{ 		if (_root == nullptr) 		{ 			_root = new Node(kv); 			_root->_col = BLACK; 			return true; 		}  		Node* parent = nullptr; 		Node* cur = _root;  		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; 			} 		}  		cur = new Node(kv); 		cur->_parent = parent; 		if (parent->_kv.first > cur->_kv.first) 		{ 			parent->_left = cur; 		} 		else 		{ 			parent->_right = cur; 		} 		while (parent && parent->_col == RED) 		{ 			Node* grandparent = parent->_parent; 			if (parent == grandparent->_left) 			{ 				Node* uncle = grandparent->_right; 				if (uncle && uncle->_col == RED) 				{ 					parent->_col = BLACK; 					uncle->_col = BLACK; 					grandparent->_col = RED;  					cur = grandparent; 					parent = cur->_parent; 				} 				else 				{ 					if (grandparent->_left == parent && parent->_left == cur) 					{ 						RotateR(grandparent); 					} 					else 					{ 						RotateLR(grandparent); 					} 					parent->_col = BLACK; 					grandparent->_col = RED; 					 					cur = grandparent; 					parent = cur->_parent; 				} 			} 			else 			{ 				Node* uncle = grandparent->_left; 					if (uncle && uncle->_col == RED) 					{ 						parent->_col = BLACK; 						uncle->_col = BLACK; 						grandparent->_col = RED;  						cur = grandparent; 						parent = cur->_parent; 					} 					else 					{ 						 						if (grandparent->_right == parent && parent->_right == cur) 						{ 							RotateL(grandparent); 						} 						else 						{ 							RotateRL(grandparent); 						} 						parent->_col = BLACK; 						grandparent->_col = RED; 						 						cur = grandparent; 						parent = cur->_parent; 					} 			} 		} 		_root->_col = BLACK; 		return true; 	} 	void InOder() 	{ 		_InOder(_root); 	} 	bool IsBalance() 	{  		return  _IsBalance(_root, 0); 	} 	~RBTree() 	{ 		Destory(_root); 		_root = nullptr; 	} private: 	bool _IsBalance(Node* root,int MaxBlack) //验证是否是红黑树 	{ 		if (root == nullptr) 		{ 			cout << MaxBlack + 1 << endl; 			return true; 		} 		Node* parent = root->_parent; 		if (_root->_col == RED) 		{ 			return false; 		} 		if (root->_col == RED && parent && parent->_col == RED) 		{ 			return false; 		} 		if (root->_col == BLACK) 		{ 			++MaxBlack; 		} 		return _IsBalance(root->_left, MaxBlack) && _IsBalance(root->_right, MaxBlack); 	} 	void RotateR(Node* root) 	{ 		Node* SubL = root->_left; 		Node* SubLR = SubL->_right; 		if (root == _root) 		{ 			_root = SubL; 		} 		else 		{ 			Node* parent = root->_parent; 			if (parent->_left == root) 			{ 				parent->_left = SubL; 			} 			else 			{ 				parent->_right = SubL; 			} 		} 		root->_left = SubLR; 		SubL->_right = root; 		SubL->_parent = root->_parent; 		root->_parent = SubL; 	} 	void RotateL(Node* root) 	{ 		Node* SubR = root->_right; 		Node* SunRL = SubR->_left; 		if (root == _root) 		{ 			_root = SubR; 		} 		else 		{ 			Node* parent = root->_parent; 			if (parent->_left == root) 			{ 				parent->_left = SubR; 			} 			else 			{ 				parent->_right = SubR; 			} 		} 		root->_right = SunRL; 		SubR->_left = root; 		SubR->_parent = root->_parent; 		root->_parent = SubR; 	} 	void RotateLR(Node* root) 	{ 		Node* SubL = root->_left; 		Node* SubLR = SubL->_right; 		RotateL(SubL); 		RotateR(root); 	} 	void RotateRL(Node* root) 	{ 		Node* SubR = root->_right; 		Node* SubRL = SubR->_left; 		RotateR(SubR); 		RotateL(root); 	} 	void _InOder(Node* root) 	{ 		if (root == nullptr) 		{ 			return; 		} 		_InOder(root->_left); 		cout << root->_kv.first << " " << root->_col << endl; 		_InOder(root->_right); 	} 	void Destory(Node* root) 	{ 		if (root == nullptr) 		{ 			return; 		} 		Destory(root->_left); 		Destory(root->_right); 		delete root; 	} 	Node* _root = nullptr; };

相关内容

热门资讯

微信怎样开金房间卡/微信链接斗... 斗牛是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:55051770许多玩家在游戏中会购买房卡来享受...
科技实测!牛牛房卡游戏代理星云... 微信游戏中心:星云大厅房卡在哪里买打开微信,添加客服微信【88355042】,进入游戏中心或相关小程...
推荐一款!金花房卡是正规的高朋... 推荐一款!金花房卡是正规的高朋联盟/房卡正版如何购买Sa9Ix苹果iPhone 17手机即将进入量产...
正规平台有哪些,金花充值房卡趣... 您好!微信趣游联盟大厅链接获取房卡可以通过以下几种方式购买: 1.微信渠道:(趣游联盟)大厅介绍:...
秒懂教程!微信的炸金花房卡怎么... 炸金花是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:66336574许多玩家在游戏中会购买房卡来享...
玩家攻略,牛牛房卡游戏代理兄弟... 兄弟大厅/新道游房卡更多详情添加微:33549083、 2、在商城页面中选择房卡选项。 ...
微信链接炸金花房卡在哪买的/微... 炸金花是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:8488009许多玩家在游戏中会购买房卡来享受...
重大通报,牛牛充值房卡超凡联盟... 重大通报,牛牛充值房卡超凡联盟/微信链接房卡卖家联系方式超凡联盟是一款非常受欢迎的游戏,咨询房/卡添...
秒懂教程!微信拼三张怎么买房卡... 拼三张是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:56001354许多玩家在游戏中会购买房卡来享...
微信买链接拼三张房卡/毛豆大厅... 拼三张是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:33903369许多玩家在游戏中会购买房卡来享...
正版授权!金花房卡怎么购买青龙... 青龙大厅是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:【3329006910】或QQ:332900...
一分钟了解!金花房卡出售新蜜瓜... 一分钟了解!金花房卡出售新蜜瓜大厅/上游房卡多少钱一张Sa9Ix苹果iPhone 17手机即将进入量...
玩家攻略,牛牛房卡批发平台芙蓉... 今 日消息,芙蓉大厅房卡添加微信33549083 苹果今日发布了 iOS 16.1 正式版更新,简单...
秒懂教程!微信牛牛房间怎么弄,... 斗牛是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:71319951许多玩家在游戏中会购买房卡来享受...
科技实测!金花房卡官网荣耀联盟... 荣耀联盟房卡更多详情添加微:33549083、 2、在商城页面中选择房卡选项。 3、根...
微信拼三张在哪里充值房卡/新星... 拼三张是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:55051770许多玩家在游戏中会购买房卡来享...
正版授权!微信金花房卡怎么弄悟... 正版授权!微信金花房卡怎么弄悟空系列/随意玩/房卡在哪里购买悟空系列/随意玩是一款非常受欢迎的游戏,...
玩家攻略,牛牛房卡批发平台昆仑... 微信游戏中心:昆仑大厅房卡在哪里买打开微信,添加客服微信【88355042】,进入游戏中心或相关小程...
一分钟了解!游戏微信牛牛房卡新... 新大圣/大圣大厅是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:【3329006910】或QQ:33...
ia攻略/金花房卡怎么购买白虎... 今 日消息,白虎大厅房卡添加微信33549083 苹果今日发布了 iOS 16.1 正式版更新,简单...