红黑树

红黑树的概念

  • 红黑树,是一种二叉搜索树,但在每个节点上增加一个存储位表示结点的颜色,可以是Red或Black。通过对任何一条从根到叶子的路径上每个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出两倍,因而是接近平衡的。

在这里插入图片描述
红黑树的性质

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

红黑树结点的定义

enum Color { RED, BLACK };

//红黑树结点的定义
template <class T>
class RBTreeNode {

	T m_data;	//结点的值域

	RBTreeNode<T> * m_left;
	RBTreeNode<T> * m_right;
	RBTreeNode<T> * m_parent;
	bool m_color;	//结点的颜色
	}

红黑树结构

  1. 为了后续实现关联式容器简单,红黑树的实现中增加一个头结点,因为根结点必须为黑色,为了与根节点进行区分,将头节点给成黑色,并且让头节点的pParent域指向红黑树的根节点,pLeft域指向红黑树中最小的结点,_pRight域指向红黑树中最大的结点,如下:
    在这里插入图片描述

红黑树的插入操作

  1. 按照二叉搜索树的规则插入新节点
template<class ValueType>
class RBTree
{
	//……
	bool Insert(const ValueType& data)
	 {
	PNode& pRoot = GetRoot();
	if (nullptr == pRoot)
	 {
	pRoot = new Node(data, BLACK);
	// 根的双亲为头节点
	pRoot->_pParent = _pHead;
	_pHead->_pParent = pRoot;
	 }
	else
	 {
	// 1. 按照二叉搜索的树方式插入新节点
	// 2. 检测新节点插入后,红黑树的性质是否造到破坏,
	// 若满足直接退出,否则对红黑树进行旋转着色处理
	 }
	// 根节点的颜色可能被修改,将其改回黑色
	pRoot->_color = BLACK;
	_pHead->_pLeft = LeftMost();
	_pHead->_pRight = RightMost();
	return true;
   }
private:
	PNode& GetRoot(){ return _pHead-   >_pParent;}
	// 获取红黑树中最小节点,即最左侧节点
	PNode LeftMost();
	// 获取红黑树中最大节点,即最右侧节点
	PNode RightMost();
private:
	PNode _pHead;
};
  1. 检测新节点插入后,红黑树的性质是否遭到破坏
    因为新节点的默认颜色是红色,因此:如果其双亲结点的颜色是黑色,没有违反红黑树任何性质,则不需要调整;但当新插入结点的双亲颜色为红色时,就违反了性质三不能有连在一起的红色结点,此时需要对红黑树分情况来讨论。

红黑树与AVL树的比较

  • 红黑树和AVL树都是高效平衡二叉树,增删改查的时间复杂度都是O(N),红黑树不追求绝对平衡,其只需保证最长路径不超过最短路径的2倍,相对而言,降低了插入和旋转的次数,所以在经常进行增删的结构中性能比AVL树更优,而且红黑树实现比较简单,所以实际运用中红黑树更多

红黑树的应用

  1. C++ STL库—map/set、mutil_map/mutil_set
  2. Java库
  3. linux内核
  4. 其他一些库
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值