c++自顶向下实现红黑树

自顶向下红黑树的详细介绍见数据结构与算法分析java语言描述第三版 Weiss著,这里只给出实现

#include <iostream>
#include <algorithm>
#include <vector>
#include <stack>
#include <random>
#include <ctime>
#include <string>
using namespace std;

//自顶向下插入和删除算法的说明见数据结构与算法分析java语言描述第三版 Weiss著
enum ColorFlag { RED, BLACK };

template <typename T>
struct RBTreeNode
{
	T data;   //节点数据域
	ColorFlag color;  //节点颜色
	RBTreeNode* left;
	RBTreeNode* right;
	RBTreeNode(T d, ColorFlag c) :data(d), color(c), left(nullptr), right(nullptr) {}
};

template <typename T>
RBTreeNode<T>* RotateLR(RBTreeNode<T>* ptr)  //对以ptr为根的子树执行先左后右双旋转,ptr成为旋转后新树根节点指针
{
	RBTreeNode<T>* p = ptr->left;
	RBTreeNode<T>* q = p->right;
	p->right = q->left;
	q->left = p;
	ptr->left = q->right;
	q->right = ptr;
	return q;
}

template <typename T>
RBTreeNode<T>* RotateRL(RBTreeNode<T>* ptr)  //对以ptr为根的子树执行先右后左双旋转,ptr成为旋转后新树根节点指针
{
	RBTreeNode<T>* p = ptr->right;
	RBTreeNode<T>* q = p->left;
	p->left = q->right;
	q->right = p;
	ptr->right = q->left;
	q->left = ptr;
	return q;
}

template <typename T>
RBTreeNode<T>* RotateR(RBTreeNode<T>* ptr)  //对以ptr为根的子树执行右单旋转,ptr成为旋转后新树根节点指针
{
	RBTreeNode<T>* p = ptr->left;
	ptr->left = p->right;
	p->right = ptr;
	return p;
}

template <typename T>
RBTreeNode<T>* RotateL(RBTreeNode<T>* ptr)  //对以ptr为根的子树执行左单旋转, ptr成为旋转后新树根节点指针
{
	RBTreeNode<T>* p = ptr->right;
	ptr->right = p->left;
	p->left = ptr;
	return p;
}

void printNULL(size_t num)
{
	for (size_t o = 1; o <= num; ++o)
		cout << " ";
	cout << "NULL" << endl;
}

template <typename T>
void printRBTree(RBTreeNode<T>* root, size_t offset)
{
	if (root == nullptr)
		cout << "NULL空树" << endl;;
	for (int i = 1; i <= offset; ++i)
		cout << " ";
	string s = to_string(root->data);
	offset += s.size() + 2;
	cout << s << ":";
	if (root->color == ColorFlag::RED)
		cout << "R";
	else
		cout << "B";
	cout << endl;
	if (root->left == nullptr)
	{
		if (root->right != nullptr)
		{
			printNULL(offset);
			printRBTree(root->right, offset);
		}
	}
	else
	{
		printRBTree(root->left, offset);
		if (root->right == nullptr)
		{
			printNULL(offset);
		}
		else
			printRBTree(root->right, offset);

	}
};

template <typename T>
int Searchd(RBTreeNode<T>* ptr, int d)
{
	if (d == 2)
		return 0;
	else
	{
		if (d == 1)
		{
			if (ptr->right == nullptr)
				return 0;
			else
				return 2;
		}
		else
		{
			if (ptr->left != nullptr)
				return 1;
			else
			{
				if (ptr->right != nullptr)
					return 2;
				else
					return 0;
			}
		}
	}
}

template <typename T>
void output(RBTreeNode<T>* ptr)  //输出以ptr为根的红黑树对应的广义表形式
{
	struct memory
	{
		RBTreeNode<T>* p;
		int direction;
		int last;
		memory(RBTreeNode<T>* p, int d, int l) :p(p), direction(d), last(l) {}
	};
	int d = 0;
	RBTreeNode<T>* const dest = ptr;
	stack<memory> arrange;
	while (true)
	{
		if (Searchd(ptr, d) == 0)
		{
			if (ptr == dest)
			{
				if (d == 0)
					cout << ptr->data << "(";
				else
				{
					if (arrange.top().last == 1)
						cout << ", ";
				}
				cout << ")";
				break;
			}
			else
			{
				if (d == 0)
				{
					if (arrange.top().last == 0)
					{
						if (arrange.top().direction == 1)
						{
							cout << ptr->data;
							arrange.top().last = 1;
						}
						else
						{
							cout << " ," << ptr->data;
							arrange.top().last = 2;
						}
					}
					else
					{
						cout << ",";
						cout << ptr->data;
						arrange.top().last = 2;
					}
				}
				else
				{
					if (arrange.top().last == 2)
						cout << ")";
					else
					{
						cout << ", )";
					}
					arrange.pop();
				}
				ptr = arrange.top().p;
				d = arrange.top().direction;
			}
		}
		else
		{
			RBTreeNode<T>* interval = nullptr;
			if (d == 0)
			{
				if (arrange.empty() == false)
				{
					if (arrange.top().last == 0)
					{
						if (arrange.top().direction == 1)
						{
							cout << ptr->data << "(";
							arrange.top().last = 1;
						}
						else
						{
							cout << " ," << ptr->data << "(";
							arrange.top().last = 2;
						}
					}
					else
					{
						cout << ",";
						cout << ptr->data << "(";
						arrange.top().last = 2;
					}
				}
				else
				{
					cout << ptr->data << "(";
				}
				arrange.push(memory(ptr, Searchd(ptr, d), 0));
				if (arrange.top().direction == 1)
					interval = ptr->left;
				else
					interval = ptr->right;
			}
			else
			{
				arrange.top().direction = 2;
				interval = ptr->right;
			}
			d = 0;
			ptr = interval;
		}
	}
}

bool examineBlackHeight(bool& TF, int& preroadblacknum, const int& blacknum)
{
	if (TF == false)
	{
		TF = true;
		preroadblacknum = blacknum;
	}
	else
	{
		if (preroadblacknum != blacknum)
		{
			cout << "从根节点到外节点的路径上黑节点数目不等,非红黑树" << endl;
			return false;
		}
	}
	return true;
}

template <typename T>
void addBlackNum(RBTreeNode<T>* ptr, int& blacknum)
{
	if (ptr->color == ColorFlag::BLACK)
		++blacknum;
}

template <typename T>
void reduceBlackNum(RBTreeNode<T>* ptr, int& blacknum)
{
	if (ptr->color == ColorFlag::BLACK)
		--blacknum;
}
template <typename T>
bool isRB(RBTreeNode<T>* root)  //判断以root为根的二叉树是否为红黑树(已假定节点颜色不是为红色就是为黑色)
{
	if (root->color == ColorFlag::RED)
	{
		cout << "根节点不为黑色,非红黑树" << endl;
		return false;
	}

	struct memory
	{
		RBTreeNode<T>* p;
		int direction;
		T lmin;
		memory(RBTreeNode<T>* p, int d) :p(p), direction(d) {}
	};
	T lmax;
	T rmin;
	T rmax;
	int d = 0;
	RBTreeNode<T>* ptr = root;
	RBTreeNode<T>* const dest = ptr;
	stack<memory> arrange;
	bool TF = false;
	int blacknum = 0;  //统计路径上黑节点个数的变量
	int preroadblacknum = 0;  //当前路径的前一路径上黑节点数目
	while (true)
	{
		int result;
		if ((result = Searchd(ptr, d)) == 0)
		{
			if (ptr == dest)
			{
				if (d == 0)
					return true;
			}

			if (d == 0)
			{
				addBlackNum(ptr, blacknum);

				if (examineBlackHeight(TF, preroadblacknum, blacknum) == false)
					return false;

				if (arrange.top().direction == 1)
				{
					arrange.top().lmin = ptr->data;
					lmax = ptr->data;
				}
				else
				{
					rmin = ptr->data;
					rmax = ptr->data;
				}
			}
			else
			{
				if (d == 1)
				{
					if (lmax >= ptr->data)
					{
						cout << "当前树非二叉搜索树,也非红黑树" << endl;
						return false;
					}

					if (ptr == dest)
						return true;

					T lmin = arrange.top().lmin;
					arrange.pop();
					if (arrange.top().direction == 1)
					{
						arrange.top().lmin = lmin;
						lmax = ptr->data;
					}
					else
					{
						rmin = lmin;
						rmax = ptr->data;
					}

				}
				else
				{
					if (rmin <= ptr->data)
					{
						cout << "当前树非二叉搜索树,也非红黑树" << endl;
						return false;
					}

					if (ptr == dest)
						return true;

					if (ptr->left == nullptr)
					{
						arrange.pop();
						if (arrange.top().direction == 1)
						{
							arrange.top().lmin = ptr->data;
							lmax = rmax;
						}
						else
							rmin = ptr->data;
					}
					else
					{
						T lmin = arrange.top().lmin;
						arrange.pop();
						if (arrange.top().direction == 1)
						{
							arrange.top().lmin = lmin;
							lmax = rmax;
						}
						else
							rmin = lmin;
					}
				}
			}
			reduceBlackNum(ptr, blacknum);
			ptr = arrange.top().p;
			d = arrange.top().direction;
		}
		else
		{
			RBTreeNode<T>* interval = nullptr;
			if (d == 0)
			{
				if (ptr->color == ColorFlag::RED)
				{
					if (result == 2)
					{
						if (ptr->right->color == ColorFlag::RED)
						{
							cout << "在根节点到外节点的路径上存在两个连续红色节点,非红黑树" << endl;
							return false;
						}
					}
					else
					{
						if (ptr->left->color == ColorFlag::RED || ptr->right != nullptr && ptr->right->color == ColorFlag::RED)
						{
							cout << "在根节点到外节点的路径上存在两个连续红色节点,非红黑树" << endl;
							return false;
						}
					}
				}
				else
					++blacknum;

				if (ptr->left == nullptr || ptr->right == nullptr)
				{
					if (examineBlackHeight(TF, preroadblacknum, blacknum) == false)
						return false;
				}

				arrange.push(memory(ptr, result));
				if (arrange.top().direction == 1)
					ptr = ptr->left;
				else
					ptr = ptr->right;
			}
			else
			{
				if (ptr->data <= lmax)
				{
					cout << "当前树非二叉搜索树,也非红黑树" << endl;
					return false;
				}
				arrange.top().direction = 2;
				ptr = ptr->right;
			}
			d = 0;
		}
	}
}

template <typename T>
void link(RBTreeNode<T>* parent, RBTreeNode<T>* cur, RBTreeNode<T>* original)
{
	if (parent->left == original)
		parent->left = cur;
	else
		parent->right = cur;
}
template <typename T>
void linkAfterRotate(RBTreeNode<T>* parent, RBTreeNode<T>* cur, RBTreeNode<T>*& root, RBTreeNode<T>* original)  //旋转后和上层重新链接
{
	if (parent != nullptr)
	{
		link(parent, cur, original);
	}
	else
		root = cur;
}

template <typename T>
bool adjust(RBTreeNode<T>*& cur, RBTreeNode<T>*& p, RBTreeNode<T>*& pp, RBTreeNode<T>*& ppp, RBTreeNode<T>*& root, bool LL_OR_RR)
{
	bool flag;
	pp->color = ColorFlag::RED;
	if (p == pp->left)
	{
		if (cur == p->left)
		{
			flag = false;
			p->color = ColorFlag::BLACK;
			RotateR(pp);
		}
		else
		{
			flag = true;
			cur->color = ColorFlag::BLACK;
			if (LL_OR_RR)
				cur = p;
			else
				cur = pp;
			p = RotateLR(pp);
		}
	}
	else
	{
		if (cur == p->left)
		{
			flag = true;
			cur->color = ColorFlag::BLACK;
			if (LL_OR_RR)
				cur = pp;
			else
				cur = p;
			p = RotateRL(pp);
		}
		else
		{
			flag = false;
			p->color = ColorFlag::BLACK;
			RotateL(pp);
		}
	}

	linkAfterRotate(ppp, p, root, pp);
	return flag;
}

template <typename T>
bool insertInRBTree(RBTreeNode<T>*& root, T& key)
{
	if (root == nullptr)
	{
		root = new RBTreeNode<T>(key, ColorFlag::BLACK);
		return true;
	}
	RBTreeNode<T>* cur = root;
	RBTreeNode<T>* p = nullptr;
	RBTreeNode<T>* pp = nullptr;
	RBTreeNode<T>* ppp = nullptr;

	bool f;
	bool LL_OR_RR;
	while (true)
	{
		if (cur->data == key)
		{
			root->color = ColorFlag::BLACK;
			return false;
		}
		else
		{
			if (key < cur->data)
			{
				LL_OR_RR = true;
				if (cur->left == nullptr)
					f = true;
				else
					f = false;
			}
			else
			{
				LL_OR_RR = false;
				if (cur->right == nullptr)
					f = true;
				else
					f = false;
			}

			if (f)
			{
				(LL_OR_RR ? cur->left : cur->right) = new RBTreeNode<T>(key, ColorFlag::RED);
				if (cur->color == ColorFlag::RED)
				{
					RBTreeNode<T>* t = (LL_OR_RR ? cur->left : cur->right);
					adjust(t, cur, p, pp, root, LL_OR_RR);
				}
				root->color = ColorFlag::BLACK;
				return true;
			}

			if (cur->left != nullptr && cur->left->color == ColorFlag::RED && cur->right != nullptr && cur->right->color == ColorFlag::RED)
			{
				cur->left->color = ColorFlag::BLACK;
				cur->right->color = ColorFlag::BLACK;
				cur->color = ColorFlag::RED;
				if (p != nullptr && p->color == ColorFlag::RED)
				{
					if (adjust(cur, p, pp, ppp, root, LL_OR_RR))
						continue;
				}
			}
			ppp = pp;
			pp = p;
			p = cur;
			cur = (LL_OR_RR ? cur->left : cur->right);
		}
	}
}

template <typename T>
bool replaceDeletedValue(RBTreeNode<T>* root, bool left_or_right, T& key)  //用root左子树(右子树)最大值(最小值)替换root
{
	RBTreeNode<T>* p = nullptr;
	RBTreeNode<T>* f = root;
	if (left_or_right)
	{
		p = root->left;
		while (p->right != nullptr)
		{
			f = p;
			p = p->right;
		}

		if (p->color == ColorFlag::RED || p->left != nullptr)
		{
			if (f == root)
				f->left = p->left;
			else
				f->right = p->left;
			if (p->color != ColorFlag::RED)
				p->left->color = ColorFlag::BLACK;
		}
	}
	else
	{
		p = root->right;
		while (p->left != nullptr)
		{
			f = p;
			p = p->left;
		}
		if (p->color == ColorFlag::RED || p->right != nullptr)
		{
			if (f == root)
				f->right = p->right;
			else
				f->left = p->right;
			if (p->color != ColorFlag::RED)
				p->right->color = ColorFlag::BLACK;
		}
	}

	root->data = p->data;
	if (p->color == ColorFlag::RED || (left_or_right ? p->left != nullptr : p->right != nullptr))
	{
		delete p;
		return true;
	}
	key = root->data;
	return false;
}

template <typename T>
RBTreeNode<T>* directDelete(RBTreeNode<T>* cur, RBTreeNode<T>* parent)
{
	RBTreeNode<T>* temp = nullptr;
	if (cur->right == nullptr)
	{
		temp = cur->left;
	}
	else
	{
		temp = cur->right;
	}

	if (parent != nullptr)
	{
		link(parent, temp, cur);
	}

	temp->color = ColorFlag::BLACK;
	delete cur;
	return temp;
}

template <typename T>
bool DelInRBTree(RBTreeNode<T>*& root, T& key)
{
	if (root == nullptr)
	{
		return false;
	}

	RBTreeNode<T>* cur = root;
	RBTreeNode<T>* parent = nullptr;
	RBTreeNode<T>* down = nullptr;
	if (root->data == key)
	{
		if (root->left == nullptr)
		{
			if (root->right == nullptr)
			{
				delete root;
				root = nullptr;
				return true;
			}
			root = directDelete(root, static_cast<RBTreeNode<T>*>(nullptr));
			return true;
		}
		else
		{
			if (root->left->color != ColorFlag::BLACK || root->right->color != ColorFlag::BLACK)
			{
				if (root->left->color != ColorFlag::BLACK)
				{
					if (replaceDeletedValue(root, true, key))
						return true;
					down = root->left;
				}
				else
				{
					if (replaceDeletedValue(root, false, key))
						return true;
					down = root->right;
				}
			}
		}
	}
	else
	{
		if (key < root->data)
		{
			down = root->left;
		}
		else
		{
			down = root->right;
		}

		if (down == nullptr)
			return false;
	}

	if ((root->left == nullptr || root->left->color == ColorFlag::BLACK) && (root->right == nullptr || root->right->color == ColorFlag::BLACK))
	{
		root->color = ColorFlag::RED;
	}
	else
	{
		if (down->color == ColorFlag::RED)
		{
			parent = cur;
			cur = down;
			down = nullptr;
		}
		else
		{
			if (down == cur->left)
			{
				swap(cur->color, cur->right->color);
				parent = RotateL(cur);
			}
			else
			{
				swap(cur->color, cur->left->color);
				parent = RotateR(cur);
			}
			root = parent;
		}
	}

	while (true)
	{
		if (cur->data == key)
		{
			if (cur->left == nullptr)
			{
				link(parent, static_cast<RBTreeNode<T>*>(nullptr), cur);
				delete cur;
				root->color = ColorFlag::BLACK;
				return true;
			}


			if (replaceDeletedValue(cur, true, key))
			{
				root->color = ColorFlag::BLACK;
				return true;
			}
			down = cur->left;
		}
		else
		{
			if (cur->left == nullptr)
			{
				root->color = ColorFlag::BLACK;
				return false;
			}

			if (down == nullptr)
			{
				if (key < cur->data)
					down = cur->left;
				else
					down = cur->right;
			}
		}

		if ((down->left == nullptr || down->left->color == ColorFlag::BLACK) && (down->right == nullptr || down->right->color == ColorFlag::BLACK))
		{
			RBTreeNode<T>* p = nullptr;
			if (down == cur->left)
				p = cur->right;
			else
				p = cur->left;

			cur->color = ColorFlag::BLACK;
			down->color = ColorFlag::RED;
			if ((p->left == nullptr || p->left->color == ColorFlag::BLACK) && (p->right == nullptr || p->right->color == ColorFlag::BLACK))
			{
				p->color = ColorFlag::RED;
			}
			else
			{
				if (down == cur->left)
				{
					if (p->left != nullptr && p->left->color == ColorFlag::RED)
						p = RotateRL(cur);
					else
					{
						p->color = ColorFlag::RED;
						p->right->color = ColorFlag::BLACK;
						RotateL(cur);
					}
				}
				else
				{
					if (p->right != nullptr && p->right->color == ColorFlag::RED)
						p = RotateLR(cur);
					else
					{
						p->color = ColorFlag::RED;
						p->left->color = ColorFlag::BLACK;
						RotateR(cur);
					}
				}
				linkAfterRotate(parent, p, root, cur);
			}
			parent = cur;
			cur = down;
		}
		else
		{
			if (down->data == key)
			{
				if (down->left != nullptr && down->left->color == ColorFlag::RED)
				{
					if (down->right == nullptr)
					{
						root->color = ColorFlag::BLACK;
						directDelete(down, cur);
						return true;
					}

					if (replaceDeletedValue(down, true, key))
					{
						root->color = ColorFlag::BLACK;
						return true;
					}
					cur = down->left;
				}
				else
				{
					if (down->left == nullptr)
					{
						root->color = ColorFlag::BLACK;
						directDelete(down, cur);
						return true;
					}

					if (replaceDeletedValue(down, false, key))
					{
						root->color = ColorFlag::BLACK;
						return true;
					}
					cur = down->right;
				}
			}
			else
			{
				bool TF;
				if ((TF = key < down->data) && down->left == nullptr || !TF && down->right == nullptr)
				{
					root->color = ColorFlag::BLACK;
					return false;
				}

				if (TF && down->left->color == ColorFlag::RED || !TF && down->right->color == ColorFlag::RED)
				{
					if (TF && down->left->color == ColorFlag::RED)
					{
						cur = down->left;
					}
					else
					{
						cur = down->right;
					}
				}
				else
				{
					parent = cur;
					cur = down;
					cur->color = ColorFlag::RED;
					RBTreeNode<T>* temp = nullptr;
					if (TF)
					{
						down = down->left;
						cur->right->color = ColorFlag::BLACK;
						temp = RotateL(cur);
					}
					else
					{
						down = down->right;
						cur->left->color = ColorFlag::BLACK;
						temp = RotateR(cur);
					}
					linkAfterRotate(parent, temp, root, cur);
					parent = temp;
					continue;
				}
			}
			parent = down;
		}
		down = nullptr;
	}
}

int main()
{
	const int N = 2000;
	vector<int> insertvalue(N);
	for (int r = 1; r <= N; ++r)
	{
		insertvalue[r - 1] = r;
		//insertvalue.push_back(r);
	}


	shuffle(insertvalue.begin(), insertvalue.end(), default_random_engine());
	RBTreeNode<int>* root = nullptr;
	for (vector<int>::const_iterator p = insertvalue.cbegin(); p != insertvalue.cend(); ++p)
	{
		int t = *p;
		bool result = insertInRBTree(root, t);
		cout << "插入" << *p << endl;
		if (result)
		{
			cout << "插入成功" << endl;
			//output(root);
			//printRBTree(root, 0);
		}
		else
		{
			cout << "插入失败" << endl;
			//exit(0);
		}

		cout << endl;
		if (isRB(root) == true)
		{
			cout << "当前树是红黑树";
			cout << endl;
		}
		else
		{
			cerr << "错误当前树不是红黑树!" << endl;
			exit(0);
		}
	}
	cout << endl;
	cout << "插入完成后删除前红黑树对应的广义表形式为:" << endl;
	//output(root);
	//printRBTree(root, 0);
	cout << endl;
	cout << endl;
	for (vector<int>::const_iterator p = insertvalue.cbegin(); p != insertvalue.cend(); ++p)
	{
		int t = *p;
		cout << "删除节点" << *p << endl;
		bool result = DelInRBTree(root, t);
		if (result)
		{
			cout << "删除成功" << endl;

			if (root != nullptr)
			{
				//output(root);
				//printRBTree(root, 0);
				cout << endl;
				if (isRB(root) == true)
				{
					cout << "当前树是红黑树";
					cout << endl;
				}
				else
				{
					cerr << "错误当前树不是红黑树!" << endl;
					exit(0);
				}
			}
			else
				cout << "NULL";
			cout << endl;
		}
		else
		{
			cout << "删除失败" << endl;
			//exit(0);
		}
	}
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值