搜索二叉树和红黑树的实现

参考了CLRS(算法导论第二版十二十三章的内容),为了能让红黑树继承搜索二叉树中的大部分方法,我修改了书中红黑树的实现方式,即不再将空节点视为黑色节点,这样一来,红黑树的规则变成了四条。

  1. 根节点为黑色
  2. 从任一节点,到叶子节点(这里的叶子节点不是空节点)的所有路径中,包含了相同个数的黑节点
  3. 任一节点非红即黑
  4. 任一节点,若其为红,则其孩子要么都为空,要么都为黑节点。

下面是搜索二叉树的实现

//e:\Projects\CLRS\CLRS\BinaryTree.h
#ifndef BINARYTREE_H
#define BINARYTREE_H
#include <fstream>
#include <cassert>
using namespace std;
template<class T,class P>
class TreeNode
{
public:
	TreeNode(T _key,P * pdata = NULL)
	{
		key = _key;
		sateliteData = pdata;
		parentNode = rightNode = leftNode = NULL;
	}
	T key;
	P * sateliteData;
	TreeNode * leftNode;
	TreeNode * rightNode;
	TreeNode * parentNode;
};
template<class T,class P>
class BinaryTree
{
public:
	BinaryTree()
	{
		root = NULL;
	}
	TreeNode<T,P> * root;
	void Inorder_Walk(ofstream &fout);
	void Inorder_Walk(TreeNode<T,P>* node,ofstream & fout);
	void Preorder_Walk(ofstream &fout);//前序
	void Preorder_Walk(TreeNode<T,P>* node,ofstream & fout,int level);

	TreeNode<T,P> * Search(T key);
	TreeNode<T,P> * Search(TreeNode<T,P>* node,T key);

	TreeNode<T,P> * Iterative_Search(T key);
	TreeNode<T,P> * Iterative_Search(TreeNode<T,P>* node,T key);
	TreeNode<T,P>* Min(TreeNode<T,P>* node);
	TreeNode<T,P>* Min();
	TreeNode<T,P>* Max(TreeNode<T,P>* node);
	TreeNode<T,P>* Max();
	TreeNode<T,P>* TreeSuccessor(TreeNode<T,P>* node);

	TreeNode<T,P>*  Insert(TreeNode<T,P>* z);
	TreeNode<T,P>* Delete(TreeNode<T,P>* z,TreeNode<T,P>*& x,TreeNode<T,P>*& p);
	void LeftRotate(TreeNode<T,P>* x);
	void RightRotate(TreeNode<T,P>* y);

	bool IsSorted(); //是二叉搜索树吗
	bool IsSorted(TreeNode<T,P>* node,T& minVal,T& maxVal); //是二叉搜索树吗

};

template<class T,class P>
bool BinaryTree<T,P>::IsSorted()
{
	if (root == NULL)
	{
		return true;
	}
	T minV,maxV;
	return IsSorted(root,minV,maxV);

}
template<class T,class P>
bool BinaryTree<T,P>::IsSorted(TreeNode<T,P>* node,T& minV,T&maxV)
{
	T lminV,lmaxV;
	T rminV,rmaxV;

	if (node->leftNode!=NULL)
	{
		bool res = IsSorted(node->leftNode,lminV,lmaxV);
		if (!res)
		{
			return false;
		}
	}
	if (node->rightNode!=NULL)
	{
		bool res = IsSorted(node->rightNode,rminV,rmaxV);
		if (!res)
		{
			return false;
		}
	}
	if (node->leftNode!=NULL)
	{
		if (lmaxV>node->key)
		{
			return false;
		}
	}
	if (node->rightNode!=NULL)
	{
		if (rminV < node->key)
		{
			return false;
		}
	}

	if (node->leftNode == NULL)
	{
		minV = node->key;
	}else{
		minV = lminV;
	}

	if (node->rightNode == NULL)
	{
		maxV = node->key;
	}else{
		maxV = rmaxV;
	}
	return true;
}

template<class T,class P>
void BinaryTree<T,P>::Preorder_Walk(ofstream &fout)
{
	if (root == NULL)
	{
		fout << "empty tree"<<endl;
	}
	Preorder_Walk(root,fout,0);
	fout << (IsSorted()?"sorted":"unsorted") << endl;

}

template<class T,class P>
void BinaryTree<T,P>::Preorder_Walk(TreeNode<T,P>* node,ofstream & fout,int level)
{
	if (node == NULL)
	{
		return;
	}
	for (int i = 0;i<level;i++)
	{
		fout << "\t";
	}
	if (node->parentNode!=NULL && node->parentNode->leftNode == node)
	{
		fout << "L:";
	}
	if (node->parentNode!=NULL && node->parentNode->rightNode == node)
	{
		fout << "R:";
	}

	fout << node->key << endl;
	Preorder_Walk(node->leftNode,fout,level + 1);
	Preorder_Walk(node->rightNode,fout,level + 1);
}

template<class T,class P>
void BinaryTree<T,P>::LeftRotate(TreeNode<T,P>* x)
{
	assert(x != NULL);
	assert(x->rightNode !=NULL);

	TreeNode<T,P>* y = x->rightNode;
	TreeNode<T,P>* p = x->parentNode;

	x->rightNode = y->leftNode;
	if (x->rightNode)
	{
		x->rightNode->parentNode = x;
	}

	y->parentNode = p;

	if (p)
	{
		if (x == p->leftNode)
			p->leftNode = y;
		else
			p->rightNode = y;
	}else{
		root = y;
	}

	x->parentNode = y;
	y->leftNode = x;
}
template<class T,class P>
void BinaryTree<T,P>::RightRotate(TreeNode<T,P>* y)
{
	assert(y != NULL);
	assert(y->leftNode !=NULL);

	TreeNode<T,P>* x = y->leftNode;
	TreeNode<T,P>* p = y->parentNode;

	y->leftNode = x->rightNode;
	if (y->leftNode)
	{
		y->leftNode->parentNode = y;
	}

	x->parentNode = p;

	if (p)
	{
		if (y == p->leftNode)
			p->leftNode = x;
		else
			p->rightNode = x;
	}else{
		root = x;
	}

	y->parentNode = x;
	x->rightNode = y;
}


//返回x为被删节点的孩子,p为被删节点的父亲(两者都可能为空)
template<class T,class P>
TreeNode<T,P>* BinaryTree<T,P>::Delete(TreeNode<T,P>* z,TreeNode<T,P>*& x,TreeNode<T,P>*& p)
{
	if (z == NULL)
	{
		x = p = NULL;
		return NULL;
	}

	TreeNode<T,P>* y;
	if (z->leftNode == NULL || z->rightNode == NULL)
	{
		y = z;
	}else
	{
		y = TreeSuccessor(z);
	}

	//////////////////////////////////////////////////////////////////////////
	//y 最多只有一个孩子

	if (y->leftNode!=NULL)
	{
		x = y->leftNode;
	}else{
		x = y->rightNode;
	}

	//如果x为空,则y没有孩子
	p = y->parentNode;
	if (x != NULL)
	{
		x->parentNode = p;
	}
	if (p == NULL)
	{
		root = x;
	}else{
		if (y == p->leftNode)
			p->leftNode = x;
		else
			p->rightNode = x;
	}

	if (y!=z)
	{
		z->key = y->key;
		z->sateliteData = y->sateliteData;
	}
	return y;
}


//返回插入节点的父节点
template<class T,class P>
TreeNode<T,P>* BinaryTree<T,P>::Insert(TreeNode<T,P>* z)
{
	TreeNode<T,P>* y = NULL;
	TreeNode<T,P>* x = root;
	while (x != NULL)
	{
		y = x;
		if (z->key < x->key)
		{
			x = x->leftNode;
		}else{
			x = x->rightNode;
		}
	}
	z->parentNode = y;
	if (y == NULL)
	{
		root = z;
	}else{
		if (z->key < y->key)
		{
			y->leftNode = z;
		}else
		{
			y->rightNode = z;
		}
	}
	return y;
}
template<class T,class P>
TreeNode<T,P>* BinaryTree<T,P>::TreeSuccessor(TreeNode<T,P>* node)
{
	if (node == NULL)
	{
		return NULL;
	}
	if (node->rightNode!=NULL)
	{
		return Min(node->rightNode);
	}
	TreeNode<T,P>* y = node->parentNode;
	while (y!=NULL && y->rightNode==node)  //node是y的右孩子
	{
		node = y;
		y = node->parentNode;
	}
	return y;
}

template<class T,class P>
TreeNode<T,P>* BinaryTree<T,P>::Max()
{
	return Max(root);
}

template<class T,class P>
TreeNode<T,P>* BinaryTree<T,P>::Max(TreeNode<T,P>* node)
{
	if (node == NULL)
	{
		return NULL;
	}
	if (node->rightNode!=NULL)
	{
		 node = node->rightNode;
	}
	return node;
}

template<class T,class P>
TreeNode<T,P>* BinaryTree<T,P>::Min()
{
	return Min(root);
}

template<class T,class P>
TreeNode<T,P>* BinaryTree<T,P>::Min(TreeNode<T,P>* node)
{
	if (node == NULL)
	{
		return NULL;
	}
	if (node->leftNode!=NULL)
	{
		node = node->leftNode;
	}
	return node;
}

template<class T,class P>
void BinaryTree<T,P>::Inorder_Walk(ofstream & fout)
{
	Inorder_Walk(root,fout);
}

template<class T,class P>
void BinaryTree<T,P>::Inorder_Walk(TreeNode<T,P>* node,ofstream & fout)
{
	if (node != NULL)
	{
		Inorder_Walk(node->leftNode,fout);
		fout << node->key << endl;
		Inorder_Walk(node->rightNode,fout);
	}
}

template<class T,class P>
TreeNode<T,P> * BinaryTree<T,P>::Search(T key)
{
	return Search(root,key);
}
template<class T,class P>
TreeNode<T,P> * BinaryTree<T,P>::Search(TreeNode<T,P>* node,T key)
{
	if (node == NULL || node->key == key)
	{
		return node;
	}
	if (key < node->key)
	{
		return Search(node->leftNode,key);
	}
	return Search(node->rightNode,key);
}

template<class T,class P>
TreeNode<T,P> * BinaryTree<T,P>::Iterative_Search(T key)
{
	return Iterative_Search(root,key);
}
template<class T,class P>
TreeNode<T,P> * BinaryTree<T,P>::Iterative_Search(TreeNode<T,P>* node,T key)
{
	while (node != NULL && node->key!=key)
	{
		if (key < node->key)
		{
			node = node->leftNode;
		}else
		{
			node = node->rightNode;
		}
	}
	return node;
}

#endif

 

红黑树继承了上面的搜索二叉树,代码如下

//e:\Projects\CLRS\CLRS\RBTree.h
#ifndef RBTREE_H
#define RBTREE_H
#include <queue>
using namespace std;

/*
  我们的实现不采用书中的NIL叶的概念,这样需要4个ruler
  1. 每个节点非红即黑(null没有颜色的概念)
  2. 根是黑色的(如果树为空,颜色就没了)
  3. 若某个节点node为红,则其孩子都是黑的
  4. 对每个节点,其到子孙叶子节点的路径上,所包含的黑色数相同

  由4和3,隐含的一点就是,某个节点为红,则其要么两个孩子为空,要么都是黑孩子。
*/
enum NodeColor
{
	BLACK,
	RED
};
template<class T,class P>
class RBNode:public TreeNode<T,P>
{
public:
	RBNode(T key,P* pData = NULL):TreeNode<T,P>(key,pData)
	{

	}
	NodeColor color;
};
template<class T,class P>
class RBTree:public BinaryTree<T,P>
{
public:
	RBTree():BinaryTree<T,P>()
	{
	}
	void Insert(RBNode<T,P>* z);
	RBNode<T,P>* Delete(RBNode<T,P>* z);

	void Preorder_Walk(ofstream &fout);
	void Preorder_Walk(RBNode<T,P>* node,ofstream & fout,int level);
	bool IsRBTree(); //计算是否符合红黑树的条件
	int GetBlackNodes(RBNode<T,P>* node);//获取node到底的黑节点个数,如果不符合红黑树的条件,则返回-1
	//RBNode<T,P> * Search(T key);
	
};
template<class T,class P>
int RBTree<T,P>::GetBlackNodes(RBNode<T,P>* node)
{
	RBNode<T,P> * nl = (RBNode<T,P>*)node->leftNode;
	RBNode<T,P> * nr = (RBNode<T,P>*)node->rightNode;
	int lnum = 0;
	int rnum = 0;
	if(nl!=NULL)
	{
		lnum = GetBlackNodes(nl);
		if (lnum == -1)
		{
			return -1;
		}
	}
	if (nr !=NULL)
	{
		rnum = GetBlackNodes(nr);
		if (rnum == -1)
		{
			return -1;
		}
	}
	
	if(lnum != rnum)
		return -1;
	return lnum + (node->color == BLACK);
}

template<class T,class P>
bool RBTree<T,P>::IsRBTree()
{
	if (root == NULL)
	{
		return true;
	}
	if(((RBNode<T,P>*)root)->color == RED)
		return false;

	queue<RBNode<T,P>* > nodes;
	nodes.push((RBNode<T,P>*)root);
	while (!nodes.empty())
	{
		RBNode<T,P>* node = nodes.front();
		nodes.pop();
		RBNode<T,P> * nl = (RBNode<T,P>*)node->leftNode;
		RBNode<T,P> * nr = (RBNode<T,P>*)node->rightNode;
		if (node->color == RED)
		{
			if ((nl==NULL && nr == NULL) ||
				(nl!=NULL && nr != NULL && nl->color == BLACK && nr->color == BLACK))
			{
				//do nothing
			}else{
				return false;
			}
		}
		if (nl!=NULL)
		{
			nodes.push(nl);
		}
		if (nr!=NULL)
		{
			nodes.push(nr);
		}
	}


	int blackNodeNum = GetBlackNodes((RBNode<T,P>*)root);
	if (blackNodeNum == -1)
	{
		return false;
	}
	return true;
		
}

//template<class T,class P>
//RBNode<T,P>* RBTree<T,P>::Search(T key)
//{
//	TreeNode<T,P>* node = BinaryTree<T,P>::Search(key);
//	return (RBNode<T,P>*)node;
//}
//
template<class T,class P>
void RBTree<T,P>::Preorder_Walk(ofstream &fout)
{
	if (root == NULL)
	{
		fout << "empty tree"<<endl;
	}
	Preorder_Walk((RBNode<T,P>*)root,fout,0);
	fout << (IsSorted()?"sorted":"unsorted") << endl;
	fout << (IsRBTree()?"rbtree":"not a rbtree") << endl;

}


//以后可以传入一个函数指针visit节点
template<class T,class P>
void RBTree<T,P>::Preorder_Walk(RBNode<T,P>* node,ofstream & fout,int level)
{
	if (node == NULL)
	{
		return;
	}
	for (int i = 0;i<level;i++)
	{
		fout << "\t";
	}
	if (node->parentNode!=NULL && node->parentNode->leftNode == node)
	{
		fout << "L:";
	}
	if (node->parentNode!=NULL && node->parentNode->rightNode == node)
	{
		fout << "R:";
	}

	fout << node->key << " " << (node->color == RED? "red":"black") << endl;
	Preorder_Walk((RBNode<T,P>*)node->leftNode,fout,level + 1);
	Preorder_Walk((RBNode<T,P>*)node->rightNode,fout,level + 1);
}
//
template<class T,class P>
RBNode<T,P>* RBTree<T,P>::Delete(RBNode<T,P>* z)
{
	RBNode<T,P>* x;
	RBNode<T,P>* p;
	TreeNode<T,P>* _x;
	TreeNode<T,P>* _p;
	RBNode<T,P>* y = (RBNode<T,P>*)BinaryTree<T,P>::Delete(z,_x,_p);
	x = (RBNode<T,P>*)_x;
	p = (RBNode<T,P>*)_p;

	//x为被删节点y的孩子,p为y的父亲,现在为x的父亲
	if (y==NULL || y->color == RED)
	{
		return y;
	}
	
	//y为黑色节点

	while (x != root && (x == NULL || x->color == BLACK))
	{
		RBNode<T,P>* w;
		if (x == p->leftNode)//p不可能为null,否则x就为root了,就不会进入此循环
		{
			w = (RBNode<T,P>*)p->rightNode;//w必定不空
			//case 1
			if (w->color == RED) //此时w的两个孩子均为黑节点(非空)
			{
				p->color = RED;
				w->color = BLACK;
				LeftRotate(p);
				w = (RBNode<T,P>*)p->rightNode;
			}

			//w必定是黑节点(非空),p的颜色未知
			RBNode<T,P>* wl = (RBNode<T,P>*)w->leftNode;
			RBNode<T,P>* wr = (RBNode<T,P>*)w->rightNode;
			if ((wl == NULL && wr == NULL) ||
				( wl!=NULL&&wr!=NULL && 
				wl->color == BLACK && wr->color == BLACK)
				)
			{
				//case 2
				w->color = RED;
				x = p;
			}else{

				//case 3
				if(wr == NULL || wr->color == BLACK)
				{
					//w->leftNode必为红
					wl->color = BLACK;
					RightRotate(w);
					w = (RBNode<T,P>*)p->rightNode;
				}

				//case 4
				//此时 w->right必为红
				wr = (RBNode<T,P>*)w->rightNode;
				wr->color = BLACK;
				w->color = p->color;
				p->color = BLACK;
				LeftRotate(p);
				x = (RBNode<T,P>*)root;
			}
		}else{
			w = (RBNode<T,P>*)p->leftNode;//w必定不空
			//case 1
			if (w->color == RED) //此时w的两个孩子均为黑节点(非空)
			{
				p->color = RED;
				w->color = BLACK;
				RightRotate(p);
				w = (RBNode<T,P>*)p->leftNode;
			}

			//w必定是黑节点(非空),p的颜色未知
			RBNode<T,P>* wl = (RBNode<T,P>*)w->leftNode;
			RBNode<T,P>* wr = (RBNode<T,P>*)w->rightNode;
			if ((wl == NULL && wr == NULL) ||
				( wl!=NULL&&wr!=NULL && 
				wl->color == BLACK && wr->color == BLACK)
				)
			{
				//case 2
				w->color = RED;
				x = p;
			}else{

				//case 3
				if(wl == NULL || wl->color == BLACK)
				{
					//w->rightNode必为红
					wr->color = BLACK;
					LeftRotate(w);
					w = (RBNode<T,P>*)p->leftNode;
				}

				//case 4
				//此时 w->left必为红
				wl = (RBNode<T,P>*)w->leftNode;
				wl->color = BLACK;
				w->color = p->color;
				p->color = BLACK;
				RightRotate(p);
				x = (RBNode<T,P>*)root;
			}

		}

		if (x!=NULL)
		{
			p = (RBNode<T,P>*)x->parentNode;
		}
	}

	if(x!=NULL)
		x->color = BLACK;
	return y;
}

template<class T,class P>
void RBTree<T,P>::Insert(RBNode<T,P>* z)
{
	//z是外面生成的节点;
	RBNode<T,P>* parent = (RBNode<T,P>*)BinaryTree<T,P>::Insert((TreeNode<T,P>*)z);//返回为新插入点的父亲
	z->color = RED;
	z->leftNode = z->rightNode = NULL;
	RBNode<T,P> * uncle;
	RBNode<T,P>* grandParent;
	//RBInsertFixup
	while (parent!=NULL && parent->color == RED)
	{
		RBNode<T,P>* grandParent = (RBNode<T,P>*)parent->parentNode;//grandParent肯定非空,且为黑色
		if (parent == grandParent->leftNode)//parent是左孩子
		{
			uncle = (RBNode<T,P>*)grandParent->rightNode; 
			//如果uncle是红色,则
			if (uncle!=NULL && uncle->color == RED)
			{
				parent->color = uncle->color = BLACK;
				grandParent->color = RED;
				z = grandParent;
			}else{//uncle是黑色或空
				if (z == parent->rightNode) //z是右孩子
				{
					z = parent;
					LeftRotate(z);
					parent = (RBNode<T,P>*)z->parentNode;
				}

				parent->color = BLACK;
				grandParent->color = RED;
				RightRotate((TreeNode<T,P>*)grandParent);
				//此时结束了
			}
		}else{ //parent是右孩子
			uncle = (RBNode<T,P>*)grandParent->leftNode;
			if (uncle!=NULL && uncle->color == RED)
			{
				parent->color = uncle->color = BLACK;
				grandParent->color = RED;
				z = grandParent;
			}else{
				if (z == parent->leftNode)
				{
					z = parent;
					RightRotate(z);
					parent = (RBNode<T,P>*)z->parentNode;
				}
				parent->color = BLACK;
				grandParent->color = RED;
				LeftRotate(grandParent);
			}
		}
		parent = (RBNode<T,P>*)z->parentNode;
	}
	((RBNode<T,P>*)root)->color = BLACK;
}

#endif
测试代码如下
#include "BinaryTree.h"
#include "RBTree.h"
#include "algorithm.h"
#include <vector>
#include <iostream>
#include <fstream>
using namespace std;
using namespace CLRS;
void TestInsertSort()
{
	int arr[] = {4,5,1,2,3,7,8,9,32,345,1,52,5,7,213,6,3};
	InsertSort(arr,sizeof(arr) / sizeof(int));
	copy(arr,arr + sizeof(arr) / sizeof(int),ostream_iterator<int>(cout, "\t"));
	cout << endl;
}
void TestMergeSort()
{
	int arr[] = {4,5,1,2,3,7,8,9,32,345,1,52,5,7,213,6,3};
	InsertSort(arr,sizeof(arr) / sizeof(int));
	copy(arr,arr + sizeof(arr) / sizeof(int),ostream_iterator<int>(cout, "\t"));
	cout << endl;
}
void TestRBTree()
{
	ofstream fout("log.txt");
	RBTree<int,int> tree;
	

	int arr[] = {4,5,1,2,3,7,8,9,32,345,1,52,5,7,213,6,3};
	for (int i = 0;i<sizeof(arr) / sizeof(int);i++)
	{
		RBNode<int,int> * node = new RBNode<int,int>(arr[i]);
		tree.Insert(node);
		fout << "after:"<<arr[i]<<" inserted"<<endl;
		tree.Preorder_Walk(fout);
	}

	int arr2[] = {5,4,1,2,3,8,9,32,1,5,7,213,7,6,3,345,52};
	for (int i = 0;i<sizeof(arr2) / sizeof(int);i++)
	{
		RBNode<int,int>* node = (RBNode<int,int>*)tree.Search(arr2[i]);
		if (node != NULL)
		{
			RBNode<int,int>* _node = tree.Delete(node);
			delete _node;
			
			fout << arr2[i] <<" deleted"<<endl;
			tree.Preorder_Walk(fout);

		}
	}
	fout.close();

}

void TestBinaryTree()
{
	ofstream fout("log.txt");
	BinaryTree<int,int> tree;

	int arr[] = {4,5,1,2,3,7,8,9,32,345,1,52,5,7,213,6,3};
	//int arr[] = {4,1,2,1,3,3};
	for (int i = 0;i<sizeof(arr) / sizeof(int);i++)
	{
		tree.Insert(new TreeNode<int,int>(arr[i]));
		fout << "after:"<<arr[i]<<" inserted"<<endl;
		tree.Preorder_Walk(fout);
	}

	int arr2[] = {5,4,1,2,3,8,9,32,1,5,7,213,7,6,3,345,52};
	for (int i = 0;i<sizeof(arr2) / sizeof(int);i++)
	{
		TreeNode<int,int>* node = tree.Search(arr2[i]);
		if (node != NULL)
		{
			TreeNode<int,int>* x;
			TreeNode<int,int>* p;

			TreeNode<int,int>* _node = tree.Delete(node,x,p);
			delete _node;
			fout << arr2[i] <<" deleted"<<endl;
			tree.Preorder_Walk(fout);

		}
	}
	fout.close();
}
//template<class T,class P>
//class A
//{
//public:
//	void func2(int x)
//	{
//		cout << "A<T,P>::func2"<<endl;
//	}
//};
//template<class T,class P>
//class B:public A<T,P>
//{
//public:
//	int func2()
//	{
//		A<T,P>::func2(4);
//		cout << "B<T,P>:func2"<<endl;
//		return 0;
//	}
//};
//void Test()
//{
//	B<int,int> b;
//	A<int,int>* pa = &b;
//	B<int,int>* pb = &b;
//	cout << (pa == pb) << endl;
//	b.func2();
//}
int main(int argc,char* argv[])
{
	//TestInsertSort();
	//TestMergeSort();
	//TestBinaryTree();
	TestRBTree();
	//Test();
	return 0;
}

posted on 2010-10-24 16:03  speedmancs  阅读(729)  评论(0编辑  收藏  举报

导航