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);
}
相关推荐
_WndProc14 分钟前
C++ 日志输出
开发语言·c++·算法
薄荷故人_15 分钟前
从零开始的C++之旅——红黑树及其实现
数据结构·c++
m0_7482400216 分钟前
Chromium 中chrome.webRequest扩展接口定义c++
网络·c++·chrome
qq_4335545423 分钟前
C++ 面向对象编程:+号运算符重载,左移运算符重载
开发语言·c++
努力学习编程的伍大侠27 分钟前
基础排序算法
数据结构·c++·算法
XiaoLeisj1 小时前
【递归,搜索与回溯算法 & 综合练习】深入理解暴搜决策树:递归,搜索与回溯算法综合小专题(二)
数据结构·算法·leetcode·决策树·深度优先·剪枝
yuyanjingtao1 小时前
CCF-GESP 等级考试 2023年9月认证C++四级真题解析
c++·青少年编程·gesp·csp-j/s·编程等级考试
Jasmine_llq1 小时前
《 火星人 》
算法·青少年编程·c#
闻缺陷则喜何志丹1 小时前
【C++动态规划 图论】3243. 新增道路查询后的最短距离 I|1567
c++·算法·动态规划·力扣·图论·最短路·路径