C++实现红黑树

//MyRbTree.h
#pragma once
#include <iostream>
const int RED = 0;
const int BLACK = 1;

struct SubRBTree
{
	SubRBTree* left;
	SubRBTree* right;
	SubRBTree* parent;
	int nData;
	int color;//RED=0,BLACK=1
	SubRBTree()//默认构造nil节点
	{
		left = NULL;
		right = NULL;
		parent = NULL;
		nData = 0;
		color = BLACK;
	}

	SubRBTree(int nData,SubRBTree*nil):nData(nData)//普通构造为红色节点
	{
		left = nil;
		right = nil;
		parent = nil;
		color = RED;
	}

//左旋
	SubRBTree* RotateLeft(SubRBTree**pRoot,SubRBTree*nil)
	{
		SubRBTree* R = right;
		right = right -> left;

		if (R->left != nil)
			R->left->parent = this;	
		
		if (this->parent == nil)
			*pRoot = R;
		else
		{
			if (this->parent->left == this)
				this->parent->left = R;
			else
				this->parent->right = R;	
		}

		R->parent = this->parent;
		this->parent = R;
		R->left = this;

		return R;
	}
//右旋
	SubRBTree* RotateRight(SubRBTree** pRoot, SubRBTree* nil)
	{
		SubRBTree* L = left;
		left = left->right;

		if (L->right != nil)
			L->right->parent = this;
	
		if (this->parent == nil)
			*pRoot = L;
		else
		{
			if (this->parent->left == this)
				this->parent->left = L;
			else
				this->parent->right = L;
		}

		L->parent = this->parent;
		this->parent = L;
		L->right = this;

		return L;
	}
};

class RBTree
{

public:
	RBTree();
	~RBTree();
public:
	bool Insert(const int nData);
	void InsertEx(const int nData);
	bool Delete(const int nData);
	void Display()
	{
		PrintTree(root,0,-1);
	}
private:

	void InsertFixup(SubRBTree* pNode);
	void InsertFixupEx(SubRBTree* pNode);
	void DeleteFixup(SubRBTree* pNode);

	SubRBTree* CreateNode(int nData);
	void DeleteNode(SubRBTree* pNode);
	SubRBTree* FindNode(const int nData);
	SubRBTree* Maximum(SubRBTree* pNode);
	SubRBTree* Minimum(SubRBTree* pNode);
//	SubRBTree* Successor(SubRBTree* pNode);

	void DeleteTree(SubRBTree* pNode);
	void PrintTree(SubRBTree* pNode,int nDepth,int state) const;

private:
	SubRBTree* root;
	SubRBTree* nil;
	int    node_count;
};

RBTree::RBTree()
{
	nil = new SubRBTree;
	root = nil;
	node_count = 0;
}

RBTree::~RBTree()
{
	DeleteTree(root);
	delete nil;
	root = NULL;
	nil = NULL;
}

SubRBTree* RBTree::CreateNode(int nData)
{
	return new SubRBTree(nData, nil);
}

void RBTree::DeleteTree(SubRBTree* pNode)
{
	if (pNode == nil)
		return;

	DeleteTree(pNode->left);
	DeleteTree(pNode->right);

	delete pNode;
	pNode = NULL;
}



SubRBTree* RBTree::Maximum(SubRBTree* pNode)
{
	while (pNode->right != nil)
		pNode = pNode->right;

	return pNode;
}

SubRBTree* RBTree::Minimum(SubRBTree* pNode)
{
	while (pNode->left != nil)
		pNode = pNode->left;

	return pNode;
}

//SubRBTree* RBTree::Successor(SubRBTree* pNode)
//{
//	if (pNode->right != nil)
//		return Minimum(pNode->right);//找后继节点
//
//	SubRBTree* pPNode = pNode->parent;
//	while (pPNode != nil && pNode == pPNode->right)
//	{
//		pNode = pPNode;
//		pPNode = pNode->parent;
//	}
//
//	return pPNode;
//}

void RBTree::InsertEx(const int nData)
{
	SubRBTree* pNewNode = CreateNode(nData);
	SubRBTree* pPNewNode = nil;
	SubRBTree* pTemp = root;

	while (pTemp != nil)
	{
		pPNewNode = pTemp;
		if (nData < pTemp->nData)
			pTemp = pTemp->left;
		else
			pTemp = pTemp->right;
	}

	//空树
	if (pPNewNode == nil)
		root = pNewNode;
	if (nData < pPNewNode->nData)
		pPNewNode->left = pNewNode;
	else
		pPNewNode->right = pNewNode;

	pNewNode->parent = pPNewNode;

	InsertFixupEx(pNewNode);

}

bool RBTree::Insert(const int nData)
{
	SubRBTree* pNewNode = CreateNode(nData);
	SubRBTree* pPNewNode = nil;
	SubRBTree* pTemp = root;

	//查找直接插入时,插入的位置,先按照正常搜索树查找
	while (pTemp != nil)
	{
		pPNewNode = pTemp;

		if (nData < pTemp->nData)
			pTemp = pTemp->left;
		else
			pTemp = pTemp->right;
	}

	pNewNode->parent = pPNewNode;

	if (pPNewNode == nil)
		root = pNewNode;
	else if (nData < pPNewNode->nData)
		pPNewNode->left = pNewNode;
	else
		pPNewNode->right = pNewNode;

	//再调整到红黑树的性质
	InsertFixup(pNewNode);

	return true;
}

void RBTree::InsertFixup(SubRBTree* pNode)
{
	while (pNode->parent->color == RED)
	{
		//pNode的父节点是其父节点的左子节点
		if (pNode->parent == pNode->parent->parent->left)
		{
			SubRBTree* pUNode = pNode->parent->parent->right;//pNode的叔父节点

			if (pUNode->color == RED)//情况三
			{
				pNode->parent->color = BLACK;
				pUNode->color = BLACK;
				pNode->parent->parent->color = RED;

				pNode = pNode->parent->parent;//变色处理,下一个要调整的节点是其祖父节点【变色是向上破坏的,而祖父节点对应的子树已经在此变换中平衡】【所以继续调整的是以其祖父节点开始】
			}
			else if (pNode == pNode->parent->right)//情况四
			{
				pNode = pNode->parent;//以父节点旋转,旋转后父节点变为子节点,再继续从这个"父"节点调整【画图理解】
				pNode->RotateLeft(&root, nil);
				//RotateLeft(pNode);
			}
			else//情况五
			{
				//调整后,继续调整时依然以这个节点开始调整
				pNode->parent->color = BLACK;
				pNode->parent->parent->color = RED;
				pNode->parent->parent->RotateRight(&root, nil);
				//RotateRight(pNode->parent->parent);
			}
		}
		else//pNode的父节点是其父节点的右子节点
		{
			SubRBTree* pUNode = pNode->parent->parent->left;//pNode的叔父节点

			if (pUNode->color == RED)//情况三
			{
				pNode->parent->color = BLACK;
				pUNode->color = BLACK;
				pNode->parent->parent->color = RED;

				pNode = pNode->parent->parent;
			}
			else if (pNode == pNode->parent->left)//情况四
			{
				pNode = pNode->parent;
				pNode->RotateRight(&root, nil);
				//RotateRight(pNode);
			}
			else情况五
			{
				pNode->parent->color = BLACK;
				pNode->parent->parent->color = RED;
				pNode->parent->parent->RotateLeft(&root, nil);
				//RotateLeft(pNode->parent->parent);
			}
		}
	}

	root->color = BLACK;//这里处理了情况一
	//情况二不用处理,自动满足红黑树性质
}

void RBTree::InsertFixupEx(SubRBTree* pNode)
{
	while (pNode->parent->color==RED)
	{
		//父节点是其祖父节点的左节点
		if (pNode->parent==pNode->parent->parent->left) {
			SubRBTree* pUNode = pNode->parent->parent->right;//pNode的叔父节点
			if (pUNode->color == RED)//情况三
			{
				pNode->parent->color = BLACK;
				pUNode->color = BLACK;
				pNode->parent->parent->color = RED;

				pNode = pNode->parent->parent;
			}
			else if(pNode==pNode->parent->right)//情况四
			{
				pNode = pNode->parent;
				pNode->RotateLeft(&root, nil);
			}
			else//情况五
			{
				pNode->parent->color = BLACK;
				pNode->parent->parent->color = RED;
				pNode->parent->parent->RotateRight(&root, nil);
			}
		}
		else
		{
			//父节点是其祖父节点的右节点
			SubRBTree* pUNode = pNode->parent->parent->left;//pNode的叔父节点
			if (pUNode->color == RED)
			{
				pNode->parent->color = BLACK;
				pUNode->color = BLACK;

				pNode->parent->parent->color = RED;

				pNode= pNode->parent->parent;
			}
			else if (pNode == pNode->parent->left)
			{
				pNode = pNode->parent;
				pNode->RotateRight(&root, nil);
			}
			else
			{
				pNode->parent->color = BLACK;
				pNode->parent->parent->color = RED;
				pNode->parent->parent->RotateLeft(&root, nil);
			}

		}
	}
	root->color = BLACK;
}

bool RBTree::Delete(const int nData)
{
	//查找要删除的节点
	SubRBTree* pDeleteNode = FindNode(nData);

	if (pDeleteNode == nil)
	{
		std::cout << "no Find" << std::endl;
		return false;
	}

	DeleteNode(pDeleteNode);

	return true;
}

SubRBTree* RBTree::FindNode(const int nData)
{
	SubRBTree* pTemp = root;

	while (pTemp != nil)
	{
		if (nData < pTemp->nData)
			pTemp = pTemp->left;
		else if (nData > pTemp->nData)
			pTemp = pTemp->right;
		else
			return pTemp;
	}

	return nil;
}

void RBTree::DeleteNode(SubRBTree* pNode)
{
	if (pNode->left != nil && pNode->right != nil)
	{
		//删除节点有二个子节点,除非删除的情况三
		SubRBTree*pNextNode=Minimum(pNode->right);//找后继节点
		pNode->nData=pNextNode->nData;
		pNode = pNextNode;
	}

	if (pNode->left != nil)
	{
		//删除节点只有一个节点,触发删除的情况二
		if (pNode->parent->left == pNode)
			pNode->parent->left = pNode->left;
		else		
			pNode->parent->right = pNode->left;
		
		pNode->left->parent = pNode->parent;
		pNode->left->color = BLACK;
		delete pNode;
	}
	else if (pNode->right != nil)
	{
		//删除节点只有一个节点,触发删除的情况二

		if (pNode->parent->left == pNode)
			pNode->parent->left = pNode->right;
		else
			pNode->parent->right = pNode->right;

		pNode->right->parent = pNode->parent;
		pNode->right->color = BLACK;
		delete pNode;
	}
	else
	{
		//删除节点 没有子节点,触发删除情况一

		if (pNode->color == RED)//删除情况1.1
		{
			if (pNode->parent->left == pNode)
				pNode->parent->left = nil;
			else
				pNode->parent->right = nil;
			delete pNode;
		}
		else//删除情况1.2
		{
			//先调整再删除,调整过程中删除节点挂在树上,最后调整完再删除;整个调整过程中(旋转,变色操作)不会让删除节点(这里指真正要删除的节点,而不是每次观察时化身的节点)获得子节点
			DeleteFixup(pNode);

			if (pNode == root)
				root = nil;
			if (pNode == pNode->parent->left)
				pNode->parent->left = nil;
			else
				pNode->parent->right = nil;

			delete pNode;
		}
			
	}
	return ;
}

void RBTree::DeleteFixup(SubRBTree* pNode)
{
	while (pNode != root && pNode->color == BLACK)//触发调整情况二,三
	{
		if (pNode == pNode->parent->left)
		{
			SubRBTree* pBNode = pNode->parent->right;//pNode的兄弟节点

			if (pBNode->color = RED)//右兄红,触发调整情况三
			{
				//变色
				pBNode->color = BLACK;
				pNode->parent->color = RED;
				
				pNode->parent->RotateLeft(&root, nil);
				//RotateLeft(pNode->parent);
				pBNode = pNode->parent->right;//重新观察,pNode删除节点不变,兄弟节点观察更新=>依然是右兄,且颜色是黑色【根据红黑树性质】
			}

			if (pBNode->left->color == BLACK && pBNode->right->color == BLACK)//触发调整情况2.1;兄黑且兄子节点全黑
			{
				//处理情况2.1.1/2.1.2
				pBNode->color = RED;//将兄节点涂红
				pNode = pNode->parent;//将pNode节点视为pNode的父节点进行观察,如果此时父节点是红色=>收敛,否则继续递归向上处理平衡操作
			}
			else if (pBNode->right->color == BLACK)//处理情况2.2
			{
				//情况2.2.2
				pBNode->left->color = BLACK;
				pBNode->color = RED;

				pBNode->RotateRight(&root, nil);
				//RotateRight(pBNode);
				pBNode = pNode->parent->right;//重新观察pNode不变,兄节点更新
			}
			else
			{
				//触发情况2.2.1
				//交换父节点和兄节点颜色,并将兄节点的右子节点涂黑
				pBNode->color = pNode->parent->color;
				pNode->parent->color = BLACK;
				pBNode->right->color = BLACK;

				pNode->parent->RotateLeft(&root, nil);
				//RotateLeft(pNode->parent);
				pNode = root;//收敛,平衡调整结束【结束后可以直接删除最开始的删除节点】
			}
		}
		else
		{
			SubRBTree* pBNode = pNode->parent->left;//pNode的兄弟节点,左兄

			if (pBNode->color = RED)//左兄红,触发调整情况三
			{
				pBNode->color = BLACK;
				pNode->parent->color = RED;

				pNode->parent->RotateRight(&root, nil);
				//RotateRight(pNode->parent);
				pBNode = pNode->parent->left;
			}

			if (pBNode->left->color == BLACK && pBNode->right->color == BLACK)//触发调整情况2.1;兄黑且兄子节点全黑
			{
				//处理情况2.1.1/2.1.2
				pBNode->color = RED;
				pNode = pNode->parent;
			}
			else if (pBNode->left->color == BLACK)//处理情况2.2
			{
				//情况2.2.2
				pBNode->right->color = BLACK;
				pBNode->color = RED;

				pBNode->RotateLeft(&root, nil);
				//RotateLeft(pBNode);
				pBNode = pNode->parent->left;
			}
			else
			{
				//触发情况2.2.1
				pBNode->color = pNode->parent->color;
				pNode->parent->color = BLACK;
				pBNode->left->color = BLACK;

				pNode->parent->RotateRight(&root, nil);
				//RotateRight(pNode->parent);
				pNode = root;
			}
		}
	}

	pNode->color = BLACK;//处理调整平衡情况2.1.2=>收敛;【收敛;需要删除的是最开始的删除节点,不一定是此时的pNode指向的节点】

	//情况一无需调整
}

void RBTree::PrintTree(SubRBTree* pNode,int nDepth,int state) const
{
	if (nil == pNode)
		return;
	
	PrintTree(pNode->left, nDepth + 1, 1);
	
	for (int i = 0; i < nDepth; i++)
		printf("     ");
	if (state == 1) // left
		printf("┌───");
	else if (state == 0)  // right
		printf("└───");

	std::cout << "[" << (pNode->color==RED ? "红:":"黑:") << pNode->nData << "]" << std::endl;
	
	PrintTree(pNode->right, nDepth + 1, 0);
}


//cpp
#include "MyRbTree.h"
#include <exception>

int main()
{
	try
	{
		RBTree rbt;
		for (int i = 1; i < 100; i++)
		{
			rbt.Insert(i);
		}
		rbt.Delete(4);
		rbt.Display();
	}
	catch (std::exception& e)
	{
		std::cout << e.what() << std::endl;
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值