数据结构【红黑树模拟实现】

目录

红黑树:基于AVL树改进

红黑树的性质

红黑树基本结构

insert基本结构

新增节点的默认颜色为红色

节点性质总结

情况一: cur为红,p为红,g为黑,u存在且为红

情况二: cur为红,p为红,g为黑,u不存在/u存在且为黑(单旋+变色)

情况三: cur为红,p为红,g为黑,u不存在/u存在且为黑(双旋+变色)

insert代码实现

验证是否为红黑树

源码链接


红黑树:基于AVL树改进

AVL树控制平衡因子,严格要求左右子树高度差不超过1,所以他的效率一直都是保持在O(logN)左右,但严格要求平衡导致其需要更多次的旋转

如果不严格要求平衡,只需要达到近似平衡,保持其性能还是处于logN数量级,减少旋转次数,可提升性能(AVL树的高度平衡是因为其通过大量的旋转来完成的,所以对于经常发生删除和插入的结构,红黑树的效率会更优,并且红黑树的实现比起AVL更加容易且易于控制,所以实际中使用红黑树更多

红黑树确保最长路径不超过最短路径的二倍,在最坏情况下,增删查改效率是O(2logN)。

红黑树概念

红黑树是一种二叉搜索树,需要在每个结点增加一个存储位表示结点的颜色,分别是Red/Black。

通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保最长路径不超过最短路径的二倍,因而接近平衡

数据结构【红黑树模拟实现】_第1张图片 11条路径

红黑树的性质

控制住颜色的规则(满足下面的性质),红黑树就能保证:其最长路径中节点个数不会超过最短路径节点个数的两倍:

1. 每个结点不是红色就是黑色

2. 根节点是黑色的 

3. 如果一个节点是红色,则它的两个孩子结点是黑色 (没有连续红节点)

4. 对于每个结点,从该结点到其所有后代叶结点的简单路径上,均包含相同数目的黑色结点(每条路径黑色节点数量相同)

5. 每个叶子结点都是黑色的(此处的叶子结点指的是空结点)

(性质5出题:空树也是红黑树,性质5中规定树中的空指针域为叶子节点,因此空树也有节点)

数据结构【红黑树模拟实现】_第2张图片

根据规则3,4可以推导出:存在最短路径一定是全黑,存在最长路径一定是一黑一红

红黑树基本结构

基本结构与AVL树相似,只是把平衡因子换成枚举标识颜色,满足性质1

enum Color
{
	RED,
	BLACK
};

template
struct RBTreeNode
{
	RBTreeNode* _left;
	RBTreeNode* _right;
	RBTreeNode* _parent;
	Color _col;
	pair _kv;

	RBTreeNode(const pair& kv)
		:_left(nullptr)
		, _right(nullptr)
		, _parent(nullptr)
		, _kv(kv)
		, _col(BLACK)
	{}
};

template
class RBTree
{
public:
	typedef RBTreeNode Node;

private:
	Node* _root;
};

insert基本结构

插入分为两个步骤:

1.按照二叉搜索树的特性插入

2.满足红黑树的性质调节颜色

insert基本结构,唯一需要改变的就是当root为根时,变为黑色,满足性质2

template
class RBTree
{
public:
	typedef RBTreeNode Node;

	bool insert(const pair& kv)
	{
		if (_root == nullptr)
		{
			_root = new Node(kv);
			_root->_col = BLACK;
			return true;
		}
		Node* cur = _root;
		Node* parent = nullptr;
		while (cur)
		{
			if (cur->_kv.first > kv.first)
			{
				parent = cur;
				cur = cur->left;
			}
			else if (cur->_kv.first < kv.first)
			{
				parent = cur;
				cur = cur->_right;
			}
			else
			{
				return false;
			}
		}
		cur = new Node(kv);
		if (parent->_kv.first > kv.first)
		{
			parent->_left = cur;
		}
		else if (parent->_kv.first < kv.first)
		{
			parent->_right = cur;
		}
		cur->_parent = parent;
	}
private:
	Node* _root;
};

新增节点的默认颜色为红色

如果此时插入30,新增的节点我们设置为红色,违反规则3

如果此时插入30,新增的节点我们设置为黑色,违反规则4

数据结构【红黑树模拟实现】_第3张图片

如果新增颜色为黑色,违反规则4,整棵树每个路径的颜色节点也都需要

你可能感兴趣的:(C++,数据结构,数据结构)