红黑树-高级的二叉查找树

#ifndef WRAPPER_H_
#define WRAPPER_H_

#include "Except.h"

template<class Object>
class Cref
{
public:
	Cref() : obj(NULL) {}
	explicit Cref(const Object & x) : obj(&x) {}

	const Object & get() const
	{
		if(isNull())
			throw NullPointerException();
		else 
			return *obj;
	}

	bool isNull() const
	{
		return obj == NULL;
	}
private:
	const Object *obj;
};


#endif

#ifndef EXCEPT_H_
#define EXCEPT_H_

#include <string>

using namespace std;

class DSException
{
public:
	DSException(const string &msg = "") : message(msg){}
	virtual ~DSException(){}
	virtual string toString() const
	{
		return "Exception " + string(": ") + what();
	}
	virtual string what() const
	{
		return message;
	}
private:
	string message;
};

class DuplicateItemException : public DSException
{
public:
	DuplicateItemException(const string & msg = ""):DSException(msg){}
};

class NullPointerException : public DSException
{
public:
	NullPointerException(const string & msg = "") : DSException(msg) {}
};


#endif

#ifndef RED_BLACK_TREE_H
#define RED_BLACK_TREE_H

#include "Except.h"
#include "Wrapper.h"

template<class Comparable>
class RedBlackTree;

template<class Comparable>
class RedBlackNode;

template<class Comparable>
class RedBlackTree
{
public:
	RedBlackTree(const Comparable & negInf); // 这个是构造函数,
	~RedBlackTree();

	Cref<Comparable> find(const Comparable & x) const;  // 自己做一个引用类型,查找的数返回的是一个引用,
	Cref<Comparable> findMin() const;
	Cref<Comparable> findMax() const;

	bool isEmpty() const;
	void makeEmpty();

	enum {RED,BLACK};

	void insert(const Comparable & x);

	typedef RedBlackNode<Comparable> Node;  // 定义一个别名,
//private:  下边是私有的,为了测试改成公有的,
public:
	Node *header; // 这个是红黑树的头,
	Node *nullNode;    // 空的节点,

	// 下面是四个指针,
	Node *current;
	Node *parent;    //父节点,
	Node *grand;    // 祖父节点,
	Node *great;   //曾祖父节点,

	void rotateWithLeftChild(Node * & k2) const;  //左孩子向右旋转
	void rotateWithRightChild(Node * & k1) const;  //右孩子向左旋转

	void doubleRotateWithLeftChild(Node * & k3) const;  // 双旋转,
	void doubleRotateWithRightChild(Node * & k1) const;

	void handleReorient(const Comparable & item);  // 这个是进行调整方向,
	RedBlackNode<Comparable> * rotate(const Comparable & item, Node *parent) const;


private:
	void reclaimMemory(Node *t) const; // 清除所有的接点,这个也可以是一个public,
};

template<class Comparable>
class RedBlackNode
{
public:     //下边是私有的,为了测试改成公有的,
	Comparable     element;
	RedBlackNode   *left;  // 左节点
	RedBlackNode   *right; // 右节点
	int            color;  // 节点的颜色,

	RedBlackNode(const Comparable & theElement = Comparable(),
		         RedBlackNode *lt = NULL,
				 RedBlackNode *rt = NULL,
	             int c = RedBlackTree<Comparable>::BLACK)
				 : element(theElement),left(lt),right(rt),color(c) {}

	friend class RedBlackTree<Comparable>;
};

template<class Comparable>
RedBlackTree<Comparable>::RedBlackTree(const Comparable & negInf)
{
	nullNode = new Node();
	nullNode->left = nullNode->right = nullNode;
	header = new Node(negInf);
	header->left = header->right = nullNode;
}

template<class Comparable>
RedBlackTree<Comparable>::~RedBlackTree()
{
	makeEmpty();
	delete nullNode;
	delete header;
}

template<class Comparable>
void RedBlackTree<Comparable>::insert(const Comparable & x)
{
	current = parent = grand = header;
	nullNode->element = x;

	while(current->element !=x)
	{
		great = grand; grand = parent; parent = current;
		current = x < current->element ? current->left : current->right;

		if(current->left->color == RED && current->right->color == RED)
			handleReorient(x);  // 两个颜色相同进行处理,
	}

	if(current != nullNode)
		throw DuplicateItemException();

	current = new Node(x,nullNode,nullNode);
	if(x < parent->element)
		parent->left = current;
	else 
		parent->right = current;
	// 自动平衡 -> 红黑树

	handleReorient(x);
}

template<class Comparable>
void RedBlackTree<Comparable>::rotateWithLeftChild(Node * & k2) const
{
	Node *k1 = k2->left;
	k2->left = k1->right;
	k1->right = k2;
	k2 = k1;
}

template<class Comparable>
void RedBlackTree<Comparable>::rotateWithRightChild(Node * & k1) const
{
	Node *k2 = k1->right;  // 这是新定义的一个指针,
	k1->right = k2->left; // k2的左边为k1的右边,
	k2->left = k1;  // k1为k2的左边,
	k1 = k2;  // k1为新的根基点,
}

template<class Comparable>
void RedBlackTree<Comparable>::doubleRotateWithLeftChild(Node * & k3) const
{
	rotateWithRightChild(k3->left);
	rotateWithLeftChild(k3);
}

template<class Comparable>
void RedBlackTree<Comparable>::doubleRotateWithRightChild(Node * & k1) const
{
	rotateWithLeftChild(k1->right);
	rotateWithRightChild(k1);
}

template<class Comparable>
void RedBlackTree<Comparable>::handleReorient(const Comparable & item)
{
	// 变色
	current->color = RED;
	current->left->color = BLACK;
	current->right->color = BLACK;

	if(parent->color == RED)
	{
		grand->color = RED;
		if(item < grand->element != item < parent->element)  // 这个是判断是内部孙子,!= 是表示不同时,
			parent = rotate(item,grand);  // 内部孙子多加一次旋转,
		current = rotate(item,great); // 这个是外部孙子,旋转一次,
		current->color = BLACK;
	}
	header->right->color = BLACK;
	// 单旋转
	// 双旋转
}

template<class Comparable>
RedBlackNode<Comparable> * RedBlackTree<Comparable>::rotate(const Comparable & item, Node *theParent) const
{
	if(item < theParent->element)
	{
		item < theParent->left->element ?
			rotateWithLeftChild(theParent->left) :
		    rotateWithRightChild(theParent->left);
			return theParent->left;
	}
	else
	{
		item < theParent->right->element ?
			rotateWithLeftChild(theParent->right) :
		    rotateWithRightChild(theParent->right);
			return theParent->right;
	}
}

template<class Comparable>
bool RedBlackTree<Comparable>::isEmpty() const
{
	return header->right == nullNode;
}

template<class Comparable>
void RedBlackTree<Comparable>::makeEmpty()
{
	reclaimMemory(header->right);
	header->right = nullNode;
}

template<class Comparable>
void RedBlackTree<Comparable>::reclaimMemory(Node* t) const
{
	if(t != t->left)
	{
		reclaimMemory(t->left);
		reclaimMemory(t->right);
		delete t;
	}
}

template<class Comparable>
Cref<Comparable> RedBlackTree<Comparable>::findMin() const
{
	if(isEmpty())
		return Cref<Comparable>();

	Node *itr = header->right;
	while(itr->left != nullNode)
		itr = itr->left;

	return Cref<Comparable>(itr->element);
}

template<class Comparable>
Cref<Comparable> RedBlackTree<Comparable>::findMax() const
{
	if(isEmpty())
		return Cref<Comparable>();

	Node *itr = header->right;
	while(itr->right != nullNode)
		itr = itr->right;

	return Cref<Comparable>(itr->element);
}

template<class Comparable>
Cref<Comparable> RedBlackTree<Comparable>::find(const Comparable & x) const 
{
	nullNode->element = x;

	Node *curr = header->right;

	for(;;)
	{
		if(x < curr->element)
			curr = curr->left;
		else if(x >curr->element)
			curr = curr->right;
		else if(curr != nullNode)
			return Cref<Comparable>(curr->element);
		else
			return Cref<Comparable>();
	}
}


#endif

#include <iostream>
#include "RedBlackTree.h"

using namespace std;

int main()
{
	const int NEG_INF = -99999; // 创建一个红黑树。就用一个很大的复数表示负无穷,
	RedBlackTree<int> t(NEG_INF);

	                          // 单旋转插入
	/*t.insert(30);
	t.insert(6);
	t.insert(70);
	t.insert(20);

	cout << t.header->right->element << endl;
	cout << t.header->right->left->element << endl;
	cout << t.header->right->right->element << endl;
	cout << t.header->right->left->right->element << endl;

	cout << "向右转" << endl;
	t.rotateWithLeftChild(t.header->right);
	cout << t.header->right->element << endl;
	cout << t.header->right->right->left->element << endl;

	cout << "向左转" << endl;
	t.rotateWithRightChild(t.header->right);
	cout << t.header->right->element << endl;
	cout << t.header->right->left->element << endl;
	cout << t.header->right->right->element << endl;
	cout << t.header->right->left->right->element << endl;*/

	                       // 双旋转插入
	//t.insert(12);
	//t.insert(16);
	//t.insert(8);
 //   t.insert(10);
	//t.insert(4);
	//t.insert(14);
	//t.insert(2);
	//t.insert(6);
	//t.insert(5);

	//cout << t.header->right->left->left->right->left->element << endl;  // 输出是5,
	//cout << t.header->right->element << endl; // 输出是12,
	//cout << t.header->right->left->element << endl;
	//cout << "旋转后" << endl;
	//t.doubleRotateWithLeftChild(t.header->right->left);
	//cout << t.header->right->left->element << endl;  // 输出是6,
	//cout << t.header->right->left->left->right->element << endl; // 输出是5,

	t.insert(60);
	t.insert(40);
	t.insert(20);

	cout << t.header->right->element << endl; // 输出的是40作为根,

	if(!t.isEmpty()) cout << "红黑树不是空的 : " << endl;

	t.makeEmpty();
	if(t.isEmpty()) cout << "红黑树是空的 : " << endl;

	t.insert(30);
	t.insert(38);
	t.insert(6);
	t.insert(3);
	t.insert(12);
	t.insert(31);

	if(t.findMin().get() == 3) cout << "找到最小的数:3 " << endl;
	cout << "最大的:" << t.findMax().get() << endl; // 输出是38,

	Cref<int> r = t.find(88);

	if(r.isNull()) 
	{
		cout << "没找到:" <<endl;
	}
	else 
	{
		cout << "找到了:" << r.get() << endl;
	}

	t.makeEmpty();
	if(t.isEmpty()) cout << "红黑树是空的 : " << endl;
	

	return 0;
}

你可能感兴趣的:(红黑树-高级的二叉查找树)