算法导论红黑树C++实现

类封装了红黑树的几个属性,水平有限,欢迎批评指正

#include "Header.h"
enum NodeColor { Red, Black };

struct RBTreeNode
{
	RBTreeNode* leftchild;
	RBTreeNode* rightchild;
	RBTreeNode* parents;
	//char color;
	NodeColor color;
	int key;
	RBTreeNode(){};
	RBTreeNode(const int &a)
	{
		key = a;
		leftchild = NULL;
		rightchild = NULL;
		parents = NULL;
		color = Black;
	}
};

class RBTree
{
public:
	RBTree();
	~RBTree();
	RBTreeNode* Root;
	RBTreeNode* Nil;
	void LeftRotate(RBTreeNode* node);
	void RightRotate(RBTreeNode* node);
	void RBInsertNode(RBTreeNode* z);
	void RBInsertFixup(RBTreeNode* z);
	void RBTDeleteFixup(RBTreeNode* x);
	void RBTrasplant(RBTreeNode* u, RBTreeNode* v);
	void RBDelete(RBTreeNode* z);
	RBTreeNode* TreeMin(RBTreeNode *Root);
	void RBTreeInorder(RBTreeNode *Root);
protected:
private:
};

RBTree::RBTree()
{
	Nil = new RBTreeNode;
	Root = new RBTreeNode;
	Nil->leftchild = Nil->rightchild = Nil-> parents = NULL;
	Nil->color = Black;
	Nil->key = 8888;
	Root = Nil;
}

RBTree::~RBTree()
{
	
	while (Root != Nil)
	{
		RBDelete(Root);
	}
	
}

void RBTree::RBTreeInorder(RBTreeNode *Root) //输出中序遍历结果
{
	//RBTreeNode* node;
	//node = Root;
	if (Root != Nil)
	{
		RBTreeInorder(Root->leftchild);
		cout << "(Key, color) = " << fixed << "(" << setw(2) << Root->key  << ", " << Root->color << ")" << endl;
		RBTreeInorder(Root->rightchild);
	}
}

RBTreeNode* RBTree::TreeMin(RBTreeNode *Root)
{
	RBTreeNode* node = new RBTreeNode;
	node = Root;
	while (node->leftchild != Nil)
	{
		node = node->leftchild;
	}

	return node;
}
void RBTree::RBInsertNode(RBTreeNode* z)
{
	//z->color = Red;
	RBTreeNode* y;
	RBTreeNode* x;
	y = Nil;
	x = Root;
	while (x != Nil)
	{
		y = x;
		if (z->key > x->key)
		{
			x = x->rightchild;
		}
		else
		{
			x = x->leftchild;
		}
	}

	z->parents = y;

	if (y == Nil)
	{
		Root = z;
	}
	else if (z->key > y->key)
	{
		y->rightchild = z;
	}
	else
	{
		y->leftchild = z;
	}

	z->leftchild = Nil;
	z->rightchild = Nil;
	z->color = Red;

	RBInsertFixup(z);
}

void RBTree::LeftRotate(RBTreeNode* node)
{
	RBTreeNode* y;
	y = new RBTreeNode;
	y = node->rightchild;
	node->rightchild = y->leftchild;


	if (y->leftchild != Nil)
	{
		y->leftchild->parents = node;
	}

	y->parents = node->parents;
	
	if (node->parents == Nil)
	{
		Root = y;
	}
	else if (node == node->parents->leftchild)
	{
		node->parents->leftchild = y;
	}
	else
	{

		node->parents->rightchild = y;
	}

	y->leftchild = node;
	node->parents = y;

}

void RBTree::RightRotate(RBTreeNode* node)
{
	RBTreeNode *y;
	y = new RBTreeNode;
	y = node->leftchild;
	node->leftchild = y->rightchild;

	if (y->rightchild != Nil)
	{
		//node->leftchild = y->rightchild;
		y->rightchild->parents = node;
	}/

	y->parents = node->parents;

	if (node->parents == Nil) /已修改,等号写成赋值号了
	{
		Root = y;
	}
	else if (node == node->parents->leftchild)
	{
		node->parents->leftchild = y;
	}
	else
	{
		node->parents->rightchild = y;///
	}

	y->rightchild = node;
	node->parents = y;
}

void RBTree::RBInsertFixup(RBTreeNode *z)
{
	while (z->parents->color == Red)
	{
		if (z->parents == z->parents->parents->leftchild) 
		///z的父亲是z的祖父的左儿子
		{
			RBTreeNode* y;
			y = z->parents->parents->rightchild;
			if (y->color == Red)                         ///情形1
			/z的叔父为红色
			{
				z->parents->color = Black;
				y->color = Black;
				z->parents->parents->color = Red;
				z = z->parents->parents;
			}
			else
			{
				if (z == z->parents->rightchild)         ///情形2,转换为情形3
				//z的叔父不是红色,且z为右孩子
				{
					z = z->parents;
					LeftRotate(z); //相当于把z变为左孩子
				}
				                                         ///情形3
				z->parents->color = Black;
				z->parents->parents->color = Red;
				RightRotate(z->parents->parents);
			}	
		}
		else///z的父亲是z的祖父的右儿子
		{
			RBTreeNode* y;
			y = z->parents->parents->leftchild;
			if (y->color == Red) /z的叔父为红色
			{
				z->parents->color = Black;
				y->color = Black;
				z->parents->parents->color = Red;
				z = z->parents->parents;
			}
			else
			{
				if (z == z->parents->leftchild)//z的叔父不是红色,且z为右孩子
				{
					z = z->parents;
					RightRotate(z); //相当于把z变为左孩子 而且转了之后,z的位置相当于回到原来的位置,与下面的z->parents->parents不矛盾
				}
				
				z->parents->color = Black;
				z->parents->parents->color = Red;
				LeftRotate(z->parents->parents);
			}
		}
	}

	Root->color = Black;
}

void RBTree::RBTrasplant(RBTreeNode* u, RBTreeNode* v)
{
	if (u->parents == Nil)
	{
		Root = v;
	}
	else if (u == u->parents->leftchild)
	{
		u->parents->leftchild = v;
	}
	else
	{
		u->parents->rightchild = v;
	}
	v->parents = u->parents;
}

void RBTree::RBDelete(RBTreeNode* z)
{
	RBTreeNode* x;
	RBTreeNode* y;
	y = z;
	NodeColor y_orignal_color = y->color;
	if (z->leftchild == Nil)
	{
		
		x = z->rightchild;
		RBTrasplant(z, z->rightchild);
	}
	else if (z->rightchild == Nil)
	{
		x = z->leftchild;
		RBTrasplant(z, z->leftchild);
	}
	else //用z的后继替代z,并集成z的属性(key, color, left, right, parents)然后维护树的性质
	{
		y = TreeMin(z->rightchild); y是z的后继(即右孩子的关键词最小的节点),则y没有左孩子了
		y_orignal_color = y->color;
		x = y->rightchild;

		if (y->parents == z)        ///z的右孩子没有左孩子,即z的后继为其右孩子
		{
			x->parents = y;
		}
		else
		{
			RBTrasplant(y, y->rightchild); //y没有左节点,用y的右节点代替y的位置
			y->rightchild = z->rightchild; //z的右孩子给y
			//第一次删除,删除根节点12, z.right = 18
			y->rightchild->parents = y;    //z的右孩子给y
		}
		RBTrasplant(z, y);
		y->leftchild = z->leftchild;
		y->leftchild->parents = y;
		y->color = z->color;
	}

	if (y_orignal_color == Black)
	{
		RBTDeleteFixup(x);
		//RBInsertFixup(x);
	}

}

void RBTree::RBTDeleteFixup(RBTreeNode* x)
{
	while (x != Root && x->color == Black)
	{
		if (x == x->parents->leftchild)
		{
			RBTreeNode* w = new RBTreeNode;
			w = x->parents->rightchild;
			if (w->color == Red)
			{
				w->color = Black;
				x->parents->color = Red;
				LeftRotate(x->parents);
				w = w->parents->rightchild;
				if (w->leftchild->color == Black && w->rightchild->color == Black)
				{
					w->color = Red;
					x = x->parents;
				}
				else
				{
					if (w->rightchild->color == Black)
					{
						w->leftchild->color = Black;
						w->color = Red;
						RightRotate(w);
						w = x->parents->rightchild;
					}
					w->color = x->parents->color;
					x->parents->color = Black;
					w->rightchild->color = Black;
					LeftRotate(x->parents);
					x = Root;
				}
			}
			delete w;
		}
		else
		{
			RBTreeNode* w = new RBTreeNode;
			w = x->parents->leftchild;
			if (w->color == Red)
			{
				w->color = Black;
				x->parents->color = Red;
				RightRotate(x->parents);
				w = w->parents->leftchild;
				if (w->rightchild->color == Black && w->leftchild->color == Black)
				{
					w->color = Red;
					x = x->parents;
				}
				else
				{
					if (w->leftchild->color == Black)
					{
						w->rightchild->color = Black;
						w->color = Red;
						LeftRotate(w);
						w = x->parents->leftchild;
					}
					w->color = x->parents->color;
					x->parents->color = Black;
					w->leftchild->color = Black;
					RightRotate(x->parents);
					x = Root;
				}
			}
			delete w;
		}
	}
}

void TestRBTree()
{
	RBTree rbt;

	int a[7] = { 12, 5, 18, 2, 9, 15, 22 };
	RBTreeNode node[7] = {};
	for (int i = 0; i < 7; i++)
	{
		node[i].key = a[i];
		node[i].leftchild = node[i].rightchild = node[i].parents = rbt.Nil;
		node[i].color = Red;
		rbt.RBInsertNode(&node[i]);
	}

	cout << rbt.Root->key << endl;
	cout << rbt.Root->color << endl;
	cout << rbt.Root->leftchild->rightchild->key << endl;
	cout << rbt.Root->rightchild->key << endl;
	if (rbt.Root->parents == rbt.Nil)
	{
		cout << "Test passed!" << endl;
	}
	cout << "生成的红黑树(中序遍历显示):" << endl;
	rbt.RBTreeInorder(rbt.Root);
	
	
	RBTreeNode node1(13);
	rbt.RBInsertNode(&node1);

	RBTreeNode node2(17);
	rbt.RBInsertNode(&node2);

	RBTreeNode node3(19);
	rbt.RBInsertNode(&node3);

	RBTreeNode node4(23);
	rbt.RBInsertNode(&node4);
	cout << "插入4个节点之后(中序遍历显示):" << endl;
	rbt.RBTreeInorder(rbt.Root);
	
	cout << "删除一个节点之后(中序遍历显示):" << endl;
	rbt.RBDelete(rbt.Root);
	rbt.RBTreeInorder(rbt.Root);
	
	
}






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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值