算法与数据结构之左偏红黑树

1.预备知识

1.1 2-3树

2-3树是由2-节点与3-节点共同组成的树,3-节点有两个键,有三个分支

但由于2-3树的实现的插入情况很多,一一实现困难,所以我们有了另外一种替代方法,即红黑树

每个节点的红色即代表该节点与其父节点构造一个3-节点,将红键拉平即是2-3树的模样

2. Node结构体

const bool RED = true;
const bool BLACK = false;//方便起见,定义常量
template<typename T1,typename T2>
class Node
{
public:
	T1 Key;
	T2 Val;
	Node<T1, T2>Left, Right;
	bool Color;//TRUE为红色,FALSE为黑色
	int N;
	Node(T1 key, T2 val,bool color)
	{
		Key = key;
		Val = val;
		Left = nullptr;
		Right = nullptr;
		N = 1;
		Color = color;
	}
};

3.旋转与确认是否为红

template<typename T1, typename T2>
Node<T1, T2>* RedBlackTree<T1, T2>::RotateLeft(Node<T1, T2>* x)
{
	Node<T1,T2>*h = x->Right;
	x->Right = h->Left;
	h->Left = x;
	h->Color = x->Color;
	x->Color = RED;
	h->N = x->N;
	x->N = size(x->Left) + size(x->Right) + 1;
	return h;
}
template<typename T1, typename T2>
Node<T1, T2>* RedBlackTree<T1, T2>::RotateRight(Node<T1, T2>* x)
{
	Node<T1, T2>*h = x->Left;
	x->Left = h->Right;
	h->Left = x;
	h->Color = x->Color;
	x->Color = RED;
	h->N = x->N;
	x->N = size(x->Left) + size(x->Right) + 1;
	return h;
}
template<typename T1, typename T2>
bool RedBlackTree<T1, T2>::IsRed(Node<T1, T2>* x)
{
	if (x == nullptr)
		return false;
	return x->Color == RED;
}

4.插入方法

4.1代码实现

template<typename T1, typename T2>
void RedBlackTree<T1, T2>::FlipColor(Node<T1, T2>* x)
{
	x->Left->Color = !x->Left->Color;
	x->Right->Color = !x->Right->Color;
	x->Color = !x->Color;
}
template<typename T1, typename T2>
Node<T1, T2>* RedBlackTree<T1, T2>::put(Node<T1, T2>* x, T1 key, T2 val)
{
	if (x == nullptr)
	{
		Node<T1, T2>*temp = new Node(key, val, RED);
		return temp;
	}
	if (x->Key > key)
		x->Left = put(x->Left, key, val);
	else if (x->Key < key)
		x->Right = put(x->Right, key, val);
	else
		x->Val = val;
	if (!IsRed(x->Left) && IsRed(x->Right))
		x = RotateLeft(x);
	if (x->Left != nullptr&&IsRed(x->Left) && IsRed(x->Left->Left))
		x = RotateRight(x);
	if (IsRed(x->Left) && IsRed(x->Right))
		FlipColor(x);
	x = size(x->Left) + size(x->Right) + 1;
	return x;
}

4.2代码解释

	if (!IsRed(x->Left) && IsRed(x->Right))
		x = RotateLeft(x);   //将红色的右节点翻转至父节点位置,而父节点变成红色的左节点
	if (x->Left != nullptr&&IsRed(x->Left) && IsRed(x->Left->Left))
		x = RotateRight(x); //将连续的两个红色节点中的第一个红色节点翻转至右
	if (IsRed(x->Left) && IsRed(x->Right))
		FlipColor(x);  //若两子节点均为红色,那么两个节点红色取消,将父节点变为红色

5.删除

5.1 平衡方法

template<typename T1, typename T2>
Node<T1, T2>* RedBlackTree<T1, T2>::Balance(Node<T1, T2>* x)
{
	if (IsRed(x->Right))
		x = RotateLeft(x);
	if (x->Left != nullptr&&IsRed(x->Left) && IsRed(x->Left->Left))
		x = RotateRight(x);
	if (IsRed(x->Left) && IsRed(x->Right))
		FlipColor(x);
	x->N = size(x->Left) + size(x->N) + 1;
	return x;
}

5.2删除最小值

公有调用:

	void DeleteMin()
	{
		if (Root == nullptr)
			return;
		if (!IsRed(Root->Left)&&!IsRed(Root->Right))
			Root->Color = RED;
		Root = DeleteMin(ROOT);
		if (Root != nullptr)
			Root->Color = BLACK;
	}

私有实现:

template<typename T1, typename T2>
Node<T1, T2>* RedBlackTree<T1, T2>::RemoveRedLeft(Node<T1, T2>* x)
{
	FlipColor(x);
	if (x->Right&&IsRed(x->Right->Left))
	{
		x->Right = RotateRight(x->Right);
		x = RotateLeft(x->Left);
		FlipColor(x);
	}
	return x;
}
template<typename T1, typename T2>
Node<T1, T2>* RedBlackTree<T1, T2>::DeleteMin(Node<T1, T2>* x)
{
	if (x->Left == nullptr)
	{
		delete x;
		return nullptr;
	}
	if (!IsRed(x->Left) && !IsRed(x->Left->Left)
		x = RemoveRedLeft(x);
	x->Left = DeleteMin(x->Left);
	return Balance(x);
}

5.3 删除最大值

公有调用

	void DeleteMax()
	{
		if (Root == nullptr)
			return;
		if (!IsRed(Root->Left) && !IsRed(Root->Right))
			Root->Color = RED;
		Root = DeleteMax(Root);
		if (Root != nullptr)
			Root->Color = BLACK;
	}

私有实现

template<typename T1, typename T2>
Node<T1, T2>* RedBlackTree<T1, T2>::RemoveRedRight(Node<T1, T2>* x)
{
	FlipColor(x);
	if (IsRed(x->Left->Left))
	{
		x = RotateRight(x);
		FlipColor(x);
	}
	return x;
}
template<typename T1, typename T2>
Node<T1, T2>* RedBlackTree<T1, T2>::DeleteMax(Node<T1, T2>* x)
{
	if (x->Right == nullptr)
	{
		delete x;
		return nullptr;
	}
	if (!IsRed(x->Right) && !IsRed(x->Right->Left))
		x = RemoveRedRight(x);
	x->Right = DeleteMax(x->Right);
	return Balance(x);
}

5.4删除方法

template<typename T>
Node<T>* RBT<T>::DeleteKey(Node<T>* h, T key)
{
	if (h->Key > key)
	{
		if (!IsRed(h->left) && !IsRed(h->left->left))
			h = MoveRedLeft(h);
		h->left = DeleteKey(h->left, key);
	}
	else
	{
		if(IsRed(h->left))
			h = RotateRight(h);
		if (h->Key == key&&h->Right == nullptr)
		{
			delete h;
			cout << "delete" << endl;
			return nullptr;
		}
		if (!IsRed(h->Right) && !IsRed(h->Right->left))
			h = MoveRedRight(h);
		if (h->Key == key)
		{
			Node<T>*temp = GetMin(h->Right);
			h->Key = temp->Key;
			h->Right = DeleteMin(h->Right);
		}
		else
			h->Right = DeleteKey(h->Right, key);
	}
	return Balance(h);
}
posted @ 2017-08-16 20:40  vhyz  阅读(737)  评论(0编辑  收藏  举报