c++红黑树,插入公式

概念

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

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

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

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

插入

其实对于红黑树来说其实就是维护好一个规则,我们插入的时候每次除了第一个节点是插入节点是黑色,以后插入的新节点都是红色,插入完我们再判断是否需要去修改颜色,和旋转。修改颜色和旋转也是有公式的。

检测新节点插入后,红黑树的性质是否造到破坏

因为新节点的默认颜色是红色,因此:如果其双亲节点的颜色是黑色,没有违反红黑树任何

性质,则不需要调整;但当新插入节点的双亲节点颜色为红色时,就违反了性质三不能有连

在一起的红色节点,此时需要对红黑树分情况来讨论:

约定:cur为当前节点,p为父节点,g为祖父节点,u为叔叔节点

情况一

每次当我们修改完颜色之后还需要向上循环去继续修改。

情况二

cur为红,p为红,g为黑,u不存在/u存在且为黑

情况三

其实就是需要双旋的情况

代码:

cpp 复制代码
	bool insert(const K&key,const V&value)
	{
		if (_node == nullptr)
		{
			_node = new rbtreeNode(make_pair(key, value));
			_node->_col = BLACK;
			return true;
		}
		rbtreeNode* root = _node;
		rbtreeNode* rootp = _node;
		while (root)
		{
			if (key < root->_kv.first)
			{
				rootp = root;
				root = root->_left;
			}
			else if(key>root->_kv.first)
			{
				rootp = root;
				root = root->_right;
			}
			else
			{
				break;
			}
		
		}

		rbtreeNode* newnode = new rbtreeNode(make_pair(key,value));
		if (key < rootp->_kv.first)
		{
			rootp->_left = newnode;
		}
		else
		{
			rootp->_right = newnode;
		}
		newnode->_parent = rootp;
		newnode->_col = RED;
		rbtreeNode* cur = newnode;
		while (rootp&&rootp->_col==RED)
		{

			rbtreeNode* grandfather = rootp->_parent;
			if (grandfather->_left == rootp)// u存在且为红 -》变色再继续往上处理
			{
				rbtreeNode* uncle = grandfather->_right;
				if (uncle && uncle->_col == RED)
				{
					uncle->_col = rootp->_col = BLACK;
					grandfather->_col = RED;
					cur = rootp;
					rootp = rootp->_parent;
					if (rootp == _node)
						break;
				}
				else
				{
					if (rootp->_left == cur)
					{
                        //    g
						//  p   u
						//c
						//单旋
						rotateR(grandfather);
						rootp->_col = BLACK;
						grandfather->_col = RED;
					}
					else
					{
						//    g
						//  p   u
						//    c
						//双旋
						rotateL(rootp);
						rotateR(grandfather);
						grandfather->_col = RED;
						cur->_col = BLACK;
					}
					break;
				}
			}
			else
			{
				rbtreeNode* uncle = grandfather->_left;
				if (uncle && uncle->_col == RED)
				{
					uncle->_col = rootp->_col = BLACK;
					grandfather->_col = RED;
					cur = rootp;
					rootp = rootp->_parent;
					if (rootp == _node)
						break;
				}
				else 
				{
					if (rootp->_right == rootp)
					{
						rotateL(grandfather);
						grandfather->_col = RED;
						rootp->_col = BLACK;
					}
					else
					{
						rotateR(rootp);
						rotateL(grandfather);
						grandfather->_col = RED;
						cur->_col = BLACK;
					}
					break;
				}
			}
		}
		_node->_col = BLACK;
		return true;

	}

红黑树的验证

这里我们也是去写一个函数去判断是否为红黑树。

cpp 复制代码
bool isrbtree()
{
	return isrbtree(_node);    //将判断函数封装起来
}

bool isrbtree(rbtreeNode*root)
{
	if (root == nullptr)
	{
		return true;
	}
	int size = 0;
	rbtreeNode* head = root;
	while (head)
	{
		if (head->_col == BLACK)
			size++;
		head = head->_left;       //找一个节点有多少个黑色节点,每条路径都有相同的黑色节点
	}

	if (_node->_col == RED)
	{
		cout << "根为红" << endl;    //如果根节点吗为红色return false
		return false;
	}

	return  iscout(root,0,size);

}

bool iscout(rbtreeNode*root,int count,int N)
{
	if (root == nullptr)
	{
		if (count == N)			//判断每条路径的高是否相同。
			return true;
		else
		{
			cout << count << " " << N << endl;
			cout << "高不同" << endl;
			return false;
		}
	}
	
	if (root->_col==BLACK)
	{
		count++;
	}

	rbtreeNode* rootp = root->_parent;
	if (rootp&&rootp->_col==RED&&root->_col==RED)
	{
		cout << "有在一起的红节点" << endl;  //判断是否有连在一起的红节点
		return false;
	}
	return iscout(root->_left, count, N) && iscout(root->_right, count, N);
}
相关推荐
猫天意8 分钟前
【CVPR2023】奔跑而非行走:追求更高FLOPS以实现更快神经网络
人工智能·深度学习·神经网络·算法·机器学习·卷积神经网络
努力努力再努力wz21 分钟前
【C++进阶系列】:万字详解红黑树(附模拟实现的源码)
java·linux·运维·c语言·开发语言·c++
cccyi726 分钟前
C/C++类型转换
c++
枫fengw27 分钟前
9.8 C++
开发语言·c++
宁檬精28 分钟前
算法练习——55.跳跃游戏
数据结构·算法·游戏
王璐WL29 分钟前
【C语言入门级教学】内存函数
c语言·开发语言·算法
啃啃大瓜29 分钟前
python常量变量运算符
开发语言·python·算法
熊文豪37 分钟前
【华为OD】找出通过车辆最多颜色
算法·华为od
Running_slave42 分钟前
位运算左移右移应该怎么玩?
前端·javascript·算法
塔中妖42 分钟前
【华为OD】环中最长子串2
算法·华为od