C++ 红黑树的实现

红黑树性质及实现详细介绍:

http://zh.wikipedia.org/zh/%E7%BA%A2%E9%BB%91%E6%A0%91

代码部分:

 头文件

// RBTree.h: interface for the CRBTree class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_RBTREE_H__9C701E48_A116_4AE0_8736_B5F45F530AF5__INCLUDED_)
#define AFX_RBTREE_H__9C701E48_A116_4AE0_8736_B5F45F530AF5__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#define BLACK 0
#define RED   1
#define NULL  0
typedef int BOOL;

typedef struct RBTreeNode
{
	int key;
	int color;
	struct RBTreeNode *parent, *left, *right;
	RBTreeNode(){}
	RBTreeNode(int k):key(k){  // 创建新结点默认颜色为红色
		color = RED;
		parent = NULL;
		left = NULL;
		right = NULL;}
}RBTree, RBTreeNode;


class CRBTree  
{
public:
	CRBTree();
	virtual ~CRBTree();

	void RB_InitLeafNode();
	BOOL RB_Insert(int keyVal);
	BOOL RB_Delete(int keyVal);
	RBTreeNode *RB_Find(int keyVal);
	void RB_Print();
	int RB_GetSize()const { return m_Size; }
private:
	void RB_Insert_FixedUp(RBTreeNode *&pNode);
	void RB_Del_FixedUp(RBTreeNode *&pNode);
	void RB_Left_Rotate(RBTreeNode *&pNode);
	void RB_Right_Rotate(RBTreeNode *&pNode);
	void RB_Print(RBTreeNode *&pNode);
	void RB_SwapTwoNodes(RBTreeNode *&pNode1, RBTreeNode *&pNode2);
	void RB_EmptyTree(RBTreeNode *&pNode);
private:
	RBTree *m_root;  //根结点
	RBTreeNode *m_NIL; // 空结点
	int m_Size;
};

#endif // !defined(AFX_RBTREE_H__9C701E48_A116_4AE0_8736_B5F45F530AF5__INCLUDED_)


 

实现文件

// RBTree.cpp: implementation of the CRBTree class.
//
//////////////////////////////////////////////////////////////////////
#include <iostream>
#include "RBTree.h"
using namespace std;

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
// 构造函数
CRBTree::CRBTree()
{
	m_root = m_NIL = NULL;
	m_Size = 0;
}

// 析构函数
CRBTree::~CRBTree()
{
	RB_EmptyTree(m_root);
	delete m_NIL;
	m_root = m_NIL = NULL;
	cout << "Empty the tree!\n";
}

// 初始化叶子结点
void CRBTree::RB_InitLeafNode()
{
	m_root = new RBTree(-1);
	m_NIL = new RBTreeNode(-1);
	m_NIL->color = BLACK;  // 叶子结点颜色都为黑色
	m_NIL->parent = NULL;
	m_NIL->left = m_NIL->right = NULL;
	m_root = m_NIL;
	m_root->parent = m_NIL;
}

// 插入树结点
BOOL CRBTree::RB_Insert( int keyVal )
{
	RBTreeNode *pNewNode = new RBTreeNode(keyVal);
	pNewNode->left = m_NIL;
	pNewNode->right = m_NIL;
	RBTreeNode *pNode = m_root;
	RBTreeNode *pPreNode = m_NIL;
	while(pNode != m_NIL)  // 树不为空
	{
		pPreNode = pNode;
		if (keyVal < pNode->key)
		{
			pNode = pNode->left;
		}
		else if (keyVal > pNode->key)
		{
			pNode = pNode->right;
		}
		else{
			delete pNewNode;
			return 0;
		}
	}
	pNewNode->parent = pPreNode;
	if (pPreNode == m_NIL)  // 树为空
	{
		pNewNode->color = BLACK;
		m_root = pNewNode;
	}
	else
	{
		if (keyVal < pPreNode->key)
		{
			pPreNode->left = pNewNode;
		}
		else
			pPreNode->right = pNewNode;
	}
	m_Size++;
	cout << "Insert "<< m_Size << " node: " << keyVal << " succeeded!\n";
	RB_Insert_FixedUp(pNewNode);
	return 1;
}

// 删除树结点
BOOL CRBTree::RB_Delete( int keyVal )
{
	RBTreeNode *pDelNode, *pPreNode = m_NIL;
	if (m_root == m_NIL)
	{
		return 0;
	}
// 	pDelNode = m_root;
// 	while(pDelNode != m_NIL)
// 	{
// 		if (keyVal < pDelNode->key)
// 		{
// 			pPreNode = pDelNode;
// 			pDelNode = pDelNode->left;
// 		}
// 		else if (keyVal > pDelNode->key)
// 		{
// 			pPreNode = pDelNode;
// 			pDelNode = pDelNode->right;
// 		}
// 		else
// 			break;
// 	}
	pDelNode = RB_Find(keyVal);
	if (pDelNode == NULL)
	{
		return 0; // 没有此结点
	}
	pPreNode = pDelNode->parent;
	//从该结点的左子树找出最大的结点或从右子树找出最小的结点, 两者的值进行替换
	RBTreeNode *pTemp;
	RBTreeNode *pDelChild;
	if (pDelNode->left != m_NIL && pDelNode->right != m_NIL)
	{ // 有两个子结点,查找左子树
		pTemp = pDelNode->left;
		while(pTemp->right != m_NIL)
		{
			pTemp = pTemp->right;
		}

		RB_SwapTwoNodes(pTemp, pDelNode);
	
		pDelChild = pTemp->left;
		pDelChild->parent = pTemp->parent;
		if (pTemp->parent->left == pTemp)
		{
			pTemp->parent->left = pDelChild;
		}
		else
			pTemp->parent->right = pDelChild;
	}
	else if (pDelNode->left == m_NIL && pDelNode->right == m_NIL)
	{ // 要删除的结点是叶子结点
		if (pPreNode == m_NIL)
		{
			delete m_root;
			m_root = m_NIL;
			m_Size--;
			return 1;
		}
		else
		{
			if (pDelNode == pDelNode->parent->left)
			{
				pPreNode->left = m_NIL;
			}
			else
				pPreNode->right = m_NIL;
			pDelChild = m_NIL;
			pDelChild->parent = pDelNode->parent;
			pTemp = pDelNode;
		}
	}
	else // 有一个子结点
	{ 
		if (pDelNode->left != m_NIL)
		{
			pDelChild = pDelNode->left;
		}
		else 
		{
			pDelChild = pDelNode->right;
		}
		if (pDelChild == pPreNode->left)
		{
			pDelChild->parent = pPreNode;
			pPreNode->left = pDelChild;
		}
		else
		{
			pDelChild->parent = pPreNode;
			pPreNode->right = pDelChild;
		}
		pTemp = pDelNode;	
	}
	if (pTemp->color == BLACK)
	{
		RB_Del_FixedUp(pDelChild);
	}
	cout << "Deleted node: " << pTemp->key << endl;
	delete pTemp;
	m_Size--;
	return 1;
}

// 查找指定结点,成功 放回该结点,否则返回NULL
RBTreeNode * CRBTree::RB_Find( int keyVal )
{
	RBTreeNode *pNode;
	if (m_root == m_NIL)
	{
		return NULL;
	}
	pNode = m_root;
	while(pNode != m_NIL)
	{
		if (keyVal < pNode->key)
		{
			pNode = pNode->left;
		}
		else if (keyVal > pNode->key)
		{
			pNode = pNode->right;
		}
		else{
			cout << "Find node: " << keyVal << "succeeded!\n";
			return pNode;
		}
	}
	return NULL;
}

// 插入结点后形成的新结构不满足红黑树性质和对其进行处理
void CRBTree::RB_Insert_FixedUp( RBTreeNode *&pNode )
{
	while (pNode->parent->color == RED)
	{
		RBTreeNode *pNodeParent = pNode->parent;
		RBTreeNode *pNodePaBro;
		if (pNodeParent->parent->left == pNodeParent) 
			pNodePaBro = pNodeParent->parent->right;
		else
			pNodePaBro = pNodeParent->parent->left;
		if (pNodePaBro->color == RED)
		{  // 父结点和叔结点都是红色 ==>> 父--黑  叔--黑  祖父--红
			pNodeParent->color = BLACK;
			pNodePaBro->color = BLACK;
			pNodeParent->parent->color = RED;
			pNode = pNode->parent->parent;
			if (pNode == m_NIL)
			{
				m_root->color = BLACK;
				return ;
			}
		}
		/// 红父 黑叔结点 或者没有叔结点
		else if(pNodeParent->parent->left == pNodeParent && pNodeParent->left == pNode)
		{
			pNodeParent->color = BLACK;
			pNodeParent->parent->color = RED;
			RB_Right_Rotate(pNode->parent->parent);
			break;
		}
		else if (pNodeParent->parent->left == pNodeParent && pNodeParent->right == pNode)
		{
			pNode = pNode->parent;
			RB_Left_Rotate(pNode);
		}
		else if (pNodeParent->parent->right == pNodeParent && pNodeParent->left == pNode)
		{
			pNode = pNode->parent;
			RB_Right_Rotate(pNode);
		}
		else 
		{
			pNodeParent->color = BLACK;
			pNodeParent->parent->color = RED;
			RB_Left_Rotate(pNode->parent->parent);
			break;
		}
	}// while
	m_root->color = BLACK;
}

// 删除结点后形成的新结构不满足红黑树性质和对其进行处理
void CRBTree::RB_Del_FixedUp( RBTreeNode *&pNode )
{
	int nLRFlag;
	RBTreeNode *pBroNode;
	while(pNode != m_root && pNode->color == BLACK)
	{
		if (pNode->parent->left == pNode)
		{
			nLRFlag = 0;
			pBroNode = pNode->parent->right;
		}
		else 
		{
			nLRFlag = 1;
			pBroNode = pNode->parent->left;
		}
		
		//1 父-red  无兄 子-red  ==>> 子-black
		//2 父-black  兄-red  ==>> 父-red 兄-black 旋转父结点 
		if (pBroNode->color == RED)
		{
			pNode->parent->color = BLACK;
			pBroNode->color = BLACK;
			if (nLRFlag == 0)
			{
				RB_Left_Rotate(pNode->parent);
			}
			else
				RB_Right_Rotate(pNode->parent);
		}
		//3 兄-black  两黑侄  ==>>	兄=红 子=黑 红父=黑 往上遍历(黑父)
		else if (pBroNode->left->color == BLACK && pBroNode->right->color == BLACK)
		{
			pNode->color = BLACK;
			pBroNode->color = RED;
			pNode->parent->color = BLACK;
			pNode = pNode->parent;  // 往上遍历
		}
		//4 兄-black  左黑侄右红侄  ==>> 兄=父色 父=黑 侄=黑 (子=黑) 左旋转父节点
		else if (pBroNode->left->color == BLACK && pBroNode->right->color == RED)
		{
			if (nLRFlag == 0)
			{
				pBroNode->color = pNode->parent->color;
				pNode->parent->color = BLACK;
				pNode->color = BLACK;
				pBroNode->right->color = BLACK;				
				RB_Left_Rotate(pNode->parent);
				break;
			}
			else 
			{
				RBTreeNode *pPa = pNode->parent;
				pBroNode->left->color = pNode->parent->color;
				pNode->parent->color = BLACK;
				RB_Left_Rotate(pBroNode);
				RB_Right_Rotate(pPa);
				break;
			}	
		}
		//5	兄-black  左红侄右黑侄  ==>> 侄=父色 父=黑 右旋转兄 左旋转父
		else if (pBroNode->left->color == RED && pBroNode->right->color == BLACK)
		{
			
			if (nLRFlag == 0)
			{
				RBTreeNode *pPa = pNode->parent;
				pBroNode->left->color = pNode->parent->color;
				pNode->parent->color = BLACK;
				RB_Right_Rotate(pBroNode);
				RB_Left_Rotate(pPa);
				break;
			}
			else 
			{
				pBroNode->color = pNode->parent->color;
				pNode->parent->color = BLACK;
				pNode->color = BLACK;
				pBroNode->right->color = BLACK;				
				RB_Right_Rotate(pNode->parent);
				break;
			}	
		}
		else  //两红侄的情况 转换成一黑一红的情况
		{
			if (nLRFlag == 0)
			{
				pBroNode->left->color = BLACK;
			}
			else
			{
				pBroNode->right->color = BLACK;
			}	
		}
	}
	pNode->color = BLACK;  //子 ==> black
	return;
}

// 左旋处理
void CRBTree::RB_Left_Rotate( RBTreeNode *&pNode )
{
	RBTreeNode *pNodeA = pNode->parent;
	RBTreeNode *pNodeB = pNode->right;
	pNode->right = pNodeB->left;
	pNodeB->left->parent = pNode;
	pNodeB->left = pNode;
	pNode->parent = pNodeB;

	if (pNode == pNodeA->left)
	{  // 父子不同边
		pNodeA->left = pNodeB;
		pNodeB->parent = pNodeA;
	}
	else if (pNode = pNodeA->right)
	{
		pNodeA->right = pNodeB;
		pNodeB->parent = pNodeA;
	}
	else // m_root == m_NIL
	{
		if (pNodeA == m_NIL)
		{  // pNode 原本为根结点
			pNodeB->parent = m_NIL;
			m_root = pNodeB;
		}
	}
	cout << "RB_Left_Rotate()\n";
}

// 右旋处理函数
void CRBTree::RB_Right_Rotate( RBTreeNode *&pNode )
{
	RBTreeNode *pNodeA = pNode->parent;
	RBTreeNode *pNodeB = pNode->left;
	pNode->left = pNodeB->right;
	pNodeB->right->parent = pNode;
	pNodeB->right = pNode;
	pNode->parent = pNodeB;
	
	if (pNode == pNodeA->right)
	{  // 父子不同边
		pNodeA->right = pNodeB;
		pNodeB->parent = pNodeA;
	}
	else if (pNode = pNodeA->left)
	{
		pNodeA->left = pNodeB;
		pNodeB->parent = pNodeA;
	}
	else // m_root == m_NIL
	{
		if (pNodeA == m_NIL)
		{  // pNodeA 原本为父结点
			pNodeB->parent = m_NIL;
			m_root = pNodeB;
		}
	}
	cout << "RB_Right_Rotate()\n";
}

void CRBTree::RB_Print()
{
	if (m_root == m_NIL)
	{
		cout << "树为空!\n";
		return ;
	}
	RB_Print(m_root);
	cout << endl;
}

void CRBTree::RB_Print( RBTreeNode *&pNode )
{
	if (pNode != m_NIL)
	{
		cout << pNode->key << "(" << pNode->color << ")  ";
		RB_Print(pNode->left);
		RB_Print(pNode->right);
	}
}

void CRBTree::RB_SwapTwoNodes( RBTreeNode *&pNode1, RBTreeNode *&pNode2 )
{
	int t = pNode1->key;
	pNode1->key = pNode2->key;
	pNode2->key = t;
}

void CRBTree::RB_EmptyTree( RBTreeNode *&pNode )
{
	if (pNode != m_NIL)
	{
		RB_EmptyTree(pNode->left);
		RB_EmptyTree(pNode->right);
		delete pNode;
	}
}


 

测试文件

//////////////////////////////////
//////////////////////////
#include <iostream>
#include "RBTree.h"
#include <Windows.h>
#include <ctime>
using namespace std;

void time_Test();
void Fun_Test();
int main()
{
	cout << "红黑树RBTree测试程序 !\n";
	Fun_Test();
	return 0;
}

void Fun_Test()
{
	CRBTree tree;
	tree.RB_InitLeafNode();
 	tree.RB_Insert(10);
 	tree.RB_Insert(14);
 	tree.RB_Insert(4);
 	tree.RB_Insert(12);
	tree.RB_Insert(11);
	tree.RB_Insert(13);
 	tree.RB_Insert(7);
 	tree.RB_Insert(16);
 	tree.RB_Print();
 	tree.RB_Delete(14);
 	tree.RB_Delete(10);
 	Sleep(1000);
	tree.RB_Print();
}

void time_Test()
{
	CRBTree tree;
	clock_t t_insert, t_print, t_find;
	int nArrNodes[50000];
	tree.RB_InitLeafNode();
	srand((unsigned)time(NULL));
//	srand(0);
	t_insert = clock();
	for (int i = 0; i < 50000; i++)
	{
		nArrNodes[i] = rand()%10000000 +1;
		while (1)
		{
			if (tree.RB_Find(nArrNodes[i]) == NULL)
			{
				tree.RB_Insert(nArrNodes[i]);
				break;
			}
			else
				nArrNodes[i] = rand()%10000000 +1;
		}
	}
	t_insert = clock() - t_insert;
	t_print = clock();
	
	tree.RB_Print();
	t_print = clock() - t_print;
	t_find = clock();
	tree.RB_Find(32725);
	t_find = clock() - t_find;
	cout << "The tree nodes count is: " << tree.RB_GetSize() << endl;
	cout << "Insert data need time: " << t_insert << "ms." << endl;
	cout << "Print data need time: " << t_print << "ms." << endl;
	cout << "Find one data need time: " << t_find << "ms." << endl;
}


 

你可能感兴趣的:(C++,tree,null,delete,insert,interface)