【C++】 ——红黑树C++完整代码

红黑树完整代码

#pragma once
#include <iostream>
using namespace std;

enum Colour
{
	BLACK,
	RED,
};

template <class T>
struct RBTreeNode
{
	RBTreeNode<T>* _left;
	RBTreeNode<T>* _right;
	RBTreeNode<T>* _parent;

	T _data;
	Colour _col;

	RBTreeNode(const T& data)
		:_left(nullptr)
		, _right(nullptr)
		, _parent(nullptr)
		, _data(data)
		, _col(RED)
	{}
};


template <class K, class V>
class RBTree
{
	typedef RBTreeNode<pair<K, V>> Node;
public:
	RBTree()
		:_root(nullptr)
	{}
	pair<Node*, bool> Insert(const pair<K, V>& kv)
	{
		if (_root == nullptr)
		{
			_root = new Node(kv);
			_root->_col = BLACK;
			return make_pair(_root, true);
		}

		Node* parent = nullptr;
		Node* cur = _root;
		while (cur)
		{
			if (cur->_data.first < kv.first)
			{
				parent = cur;
				cur = cur->_right;
			}
			else if (cur->_data.first > kv.first)
			{
				parent = cur;
				cur = cur->_left;
			}
			else
			{
				return make_pair(cur, false);
			}
		}

		Node* newnode = new Node(kv);
		cur = newnode;
		cur->_col = RED;

		
		if (parent->_data.first < kv.first)
		{
			parent->_right = cur;
			cur->_parent = parent;
		}
		else
		{
			parent->_left = cur;
			cur->_parent = parent;
		}

		//调整红黑树节点颜色
		while (parent && parent->_col == RED) //父亲节点存在 且父亲节点为红 开始调整节点颜色
		{
			//关键看叔叔
			Node* grandfather = parent->_parent;
			if (parent == grandfather->_left)         //如果插入节点cur的父亲节点是祖父的左节点, 那么叔叔节点肯定是祖父的右节点
			{
				Node* uncle = grandfather->_right;
				//情况一
				if (uncle && uncle->_col == RED)
				{
					parent->_col = uncle->_col = BLACK;
					grandfather->_col = RED;


					//向上调整
					cur = grandfather;
					parent = cur->_parent;
				}

				

				else //情况二 + 情况三  uncle不存在或者存在且为黑
				{
				//情况二
					//    g
					//  p
					//c
					if (cur == parent->_left) //grandfather 节点肯定为黑,因为parent节点一直为红
					{
					//右旋
						RotateR(grandfather);
						grandfather->_col = RED;
						parent->_col = BLACK;

					}
				// 情况三 左右双旋
					//    g
					//  p
					//    c
					else  //cur == parent->_right  双旋
					{
						RotateLR(grandfather);
						cur->_col = BLACK;
						grandfather->_col = RED;
					}
					//跳出循环
					break;

				}
			}
			else//如果插入节点cur在父节点的右边的
			{
				Node* uncle = grandfather->_left;  //叔叔节点是父节点的右边
				//情况一  uncle存在且为红
				if (uncle && uncle->_col == RED)
				{
					uncle->_col = parent->_col = BLACK;
					grandfather->_col = RED;

					cur = grandfather;
					parent = cur->_parent;
				}
				else 
				{	//旋转 + 变色   
					//uncle不存在 或 存在且为黑
					//情况二
					// g
					//    p
					//       cur
					if (cur == parent->_right) //单旋 左低右高 左单旋
					{
						RotateL(grandfather);
						parent->_col = BLACK;
						grandfather->_col = RED;
					}
					//情况三
					else  //cur插入在 parent->_left
					{
						// g
						//   p
						// c
						//右左双旋
						RotateRL(grandfather);
						cur->_col = BLACK;
						grandfather->_col = RED;
					}

					break;
				}
				
			}
		}
		_root->_col = BLACK;

		return make_pair(cur, true);
	}
	//左旋
	void RotateL(Node* parent)
	{
		Node* subR = parent->_right;
		Node* subRL = subR->_left;

		parent->_right = subRL;
		if (subRL)
			subRL->_parent = parent;

		Node* Pparent = parent->_parent;
		parent->_parent = subR;
		subR->_left = parent;
		

		if (_root == parent)
		{
			_root = subR;
			subR->_parent = NULL;
		}
		else
		{
			if (Pparent)
			{
				if (Pparent->_left == parent)
				{
					Pparent->_left = subR;
				}
				else
				{
					Pparent->_right = suR;
				}
			}
			subR->_parent = Pparent;
		}
		
		
	}

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

		parent->_left = subLR;
		if (subLR)
		{
			subLR->_parent = parent;
		}

		Node* Pparent = parent->_parent;
		subL->_right = parent;
		parent->_parent = subL;
	

		if (parent == _root) //根节点的情况
		{
			_root = subL;
			subL->_parent = nullptr;
		}
		else //非根节点的情况
		{
			if (Pparent->_left == parent)
			{
				Pparent->_left = subL;
			}
			else
			{
				Pparent->_right = subL;
			}
			subL->_parent = Pparent;
		}
		
	}
	void RotateRL(Node* parent) //右左双旋 
	{
		RotateR(parent->_right);
		RotateL(parent);
	}
	void RotateLR(Node* parent)
	{
		RotateL(parent->_left);
		RotateR(parent);
	}
private:
	Node* _root;
};

原创文章 78 获赞 21 访问量 3550

猜你喜欢

转载自blog.csdn.net/Vicky_Cr/article/details/105480036
今日推荐