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);
}
相关推荐
passer__jw7671 小时前
【LeetCode】【算法】3. 无重复字符的最长子串
算法·leetcode
passer__jw7671 小时前
【LeetCode】【算法】21. 合并两个有序链表
算法·leetcode·链表
sweetheart7-72 小时前
LeetCode22. 括号生成(2024冬季每日一题 2)
算法·深度优先·力扣·dfs·左右括号匹配
李元豪3 小时前
【智鹿空间】c++实现了一个简单的链表数据结构 MyList,其中包含基本的 Get 和 Modify 操作,
数据结构·c++·链表
我不是星海3 小时前
1.集合体系补充(1)
java·数据结构
UestcXiye3 小时前
《TCP/IP网络编程》学习笔记 | Chapter 9:套接字的多种可选项
c++·计算机网络·ip·tcp
一丝晨光4 小时前
编译器、IDE对C/C++新标准的支持
c语言·开发语言·c++·ide·msvc·visual studio·gcc
景鹤4 小时前
【算法】递归+回溯+剪枝:78.子集
算法·机器学习·剪枝
_OLi_5 小时前
力扣 LeetCode 704. 二分查找(Day1:数组)
算法·leetcode·职场和发展
丶Darling.5 小时前
Day40 | 动态规划 :完全背包应用 组合总和IV(类比爬楼梯)
c++·算法·动态规划·记忆化搜索·回溯