红黑树代码实现

红黑树对比AVL树的区别就是,红黑树的旋转次数更少,但是查找的效率会略比AVL树低,因为红黑树会比AVL树高一些。

概念:

1.红黑树的根节点必须为黑色。

2.红黑树节点不允许有连续的红色。

3.叶子节点都是黑色的(此处叶子节点是指空节点)。

4.每条路径上的黑色节点相等

满足上面的4个性质,就能保证,最长路径的节点个数,不超过最短路径的二倍。

节点的定义

enum Color//定义颜色
{
	red,
	black
};

template <class T>
struct TreeNode
{
	typedef TreeNode<T> Node;

	TreeNode(const T& data)
		:_left(nullptr)
		,_right(nullptr)
		,_parent(nullptr)
		,_Color(red)
		,_data(data)
	{}

	TreeNode<T>* _left;
	TreeNode<T>* _right;
	TreeNode<T>* _parent;
	T _data;
	Color _Color;
};

插入

插入的节点一定是红色节点,因为如果插入黑色节点就不能保证,每条路径上的黑色节点相等。

插入方法就是比当前节点小就去左边,比当前节点大就去右边,知道当前节点为空,就插入。

插入之后,就要开始改变颜色或者旋转,使插入之后仍然满足红黑树的规则。

可以分为2种情况

1.舅舅存在且为红色

这是最简单的情况

为了保证不能出现连续的红节点,需要把parent和uncle变为黑色。

保证每条路径上的黑色节点相等,将grand变为红色,如果grand是root节点,那就不变,为什呢,因为这颗树可能是一颗子树,将uncle,parent变黑,如果不将grand变红,这颗子树的路径就会多出一个黑节点。

然后一直向上调整,直到是根节点或者没有连续的红节点。

2.舅舅不存在或者舅舅存在且为黑

舅舅存在且为黑的情况,说明cur是由情况1变红的。

舅舅不存在,cur一定是新插入的节点

需要进行旋转,如果cur和parent在一条线上进行,以parent右单旋。

不在一条直线对parent进行左旋,然后对grand进行右旋。

上面都是parent在左变的的情况,还有parent在右边的情况。

std::pair<iterator,bool> insert(const T& data)
	{
		Node* cur = _root;
		Node* parent = nullptr;
		if (_root == nullptr)//当root为空时
		{
			_root = new Node(data);
			_root->_Color = black;
			return std::make_pair(iterator(_root),true);
		}
		TofK tk;

		while (cur)//寻找插入位置
		{
			if (tk(cur->_data) > tk(data))
			{
				parent = cur;
				cur = cur->_left;
			}
			else if (tk(cur->_data) < tk(data))
			{
				parent = cur;
				cur = cur->_right;
			}
			else
			{
				return std::make_pair(iterator(cur), false);
			}
		}

		cur = new Node(data);

		Node* newnode = cur;
		cur->_parent = parent;
		if (tk(cur->_data) > tk(parent->_data))//连接父亲节点
		{
			parent->_right = cur;
		}
		else
		{
			parent->_left = cur;
		}

		//开始调整颜色
		
		while (parent != nullptr && parent->_Color == red)
		{
			Node* grand = parent->_parent;
			if (cur->_Color == red && parent->_Color == red)//连续红节点
			{
				if (parent == grand->_left)//父亲是爷爷的左节点
				{
					Node* uncle = grand->_right;
					if (uncle != nullptr && uncle->_Color == red)//舅舅存在且为红
					{
						parent->_Color = black;
						uncle->_Color = black;
						grand->_Color = red;
						cur = grand;
						parent = cur->_parent;
					}
					else if (uncle == nullptr || uncle->_Color == black)//舅舅不存在||舅舅存在且为黑
					{
						if (cur == parent->_left)//在一条直线上
						{
							RotateR(grand);
							grand->_Color = red;
							parent->_Color = black;
						}
						else//不在一条直线上
						{
							RotateL(parent);
							RotateR(grand);
							cur->_Color = black;
							grand->_Color = red;
						}
						break;
					}
				}
				else//父亲是爷爷的右节点
				{
					Node* uncle = grand->_left;
					if (uncle != nullptr && uncle->_Color == red)//舅舅存在且为红
					{
						parent->_Color = black;
						uncle->_Color = black;
						grand->_Color = red;
						cur = grand;
						parent = cur->_parent;
					}
					else if (uncle == nullptr || uncle->_Color == black)//舅舅不存在||舅舅存在且为黑
					{
						if (cur == parent->_right)//在一条直线上
						{
							RotateL(grand);
							grand->_Color = red;
							parent->_Color = black;
						}
						else//不在一条直线上
						{
							RotateR(parent);
							RotateL(grand);
							cur->_Color = black;
							grand->_Color = red;
						}
						break;
					}
				}
			}//连续红节点
		 }

		_root->_Color = black;
		return std::make_pair(iterator(newnode), true);
	}

	void RotateL(Node* parent)
	{
		Node* subR = parent->_right;
		Node* subRL = subR->_left;
		Node* ppNode = parent->_parent;

		subR->_left = parent;
		parent->_parent = subR;

		parent->_right = subRL;
		if (subRL != nullptr)
		{
			subRL->_parent = parent;
		}

		if (parent == _root)
		{
			_root = subR;
			subR->_parent = nullptr;
		}
		else
		{
			if (parent == ppNode->_left)
			{
				ppNode->_left = subR;
			}
			else
			{
				ppNode->_right = subR;
			}
			subR->_parent = ppNode;
		}
		

	}

	void RotateR(Node* parent)
	{
		Node* subL = parent->_left;
		Node* subLR = subL->_right;
		Node* ppNode = parent->_parent;

		subL->_right = parent;
		parent->_parent = subL;

		parent->_left = subLR;
		if (subLR != nullptr)
		{
			subLR->_parent = parent;
		}
		if (parent == _root)
		{
			_root = subL;
			subL->_parent = nullptr;
		}
		else
		{
			if (parent == ppNode->_left)
			{
				ppNode->_left = subL;
			}
			else
			{
				ppNode->_right = subL;
			}
			subL->_parent = ppNode;
		}
		
	}

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值