红黑树C++完整版

这里写代码片//异常类
///
Except.h
///

#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

//
Wrapper.h
//

#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) {}
		Object &get() const {
			if(isNull()) {
				throw NullPointerException();
			} else {
				return *obj;
			}
		}
		bool isNull() const {
			return obj == NULL;
		}
	private:
		Object *obj;
};

#endif

///
RedBlackTree.h 最最核心类
//

#ifndef RED_BLACK_TREE_H_
#define RED_BLACK_TREE_H_

#include "Except.h"
#include "Wrapper.h"
/*
*红黑树规则:
*1.每一个节点不是红色就是黑色
*2.根总是黑色的
*3.如果节点是红色,则他的子节点必须是黑色的
*4.从根到叶节点的每条路径,必须包含相同数目的黑色节点
*/

template <class Comparable>
class RedBlackTree;

template <class Comparable>
class RedBlackNode;

template <class Comparable>
class RedBlackTree {

	public:
		enum {
		    RED,BLACK
		};
		RedBlackTree(const Comparable &negInf);
		~RedBlackTree();
		void insert(const Comparable &x);
		Cref<Comparable> find(const Comparable &x);
		Cref<Comparable> findMin() const;
		Cref<Comparable> findMax() const;
		bool isEmpty() const;
		void makeEmpty();
		typedef RedBlackNode<Comparable> Node;
	private:
		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 *theParent) const;
		void reclaimMemory(Node* t) const;

};

template <class Comparable>
class RedBlackNode {

	private:
		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() {

	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;
	//k2下降
	k1->right = k2;
	//k1上升成为根
	k2 = k1;

}

//带着右孩子向左移动
template <class Comparable>
void RedBlackTree<Comparable>::rotateWithRightChild(Node* &k1) const {

	Node *k2 = k1->right;
	//横向移动
	k1->right = k2->left;
	//k1下降
	k2->left = k1;
	//k2上升成为根
	k1 = k2;

}

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;
		//判断是内部孙子还是外部孙子
		/*
		*如果item小于爷爷 且 item小于爸爸 则是左外部孙子
		*如果item大于爷爷 且 item大于爸爸 则是右外部孙子
		*外部孙子做单旋转
		*如果两个条件不同时满足则是内部孙子
		*内部孙子做爽旋转
		*/
		if(item < grand->element != item < parent->element) {
			//内部孙子加多一次旋转
			parent = rotate(item,grand);
		}
		current = rotate(item,great);
		current->color = BLACK;
	}
	header->right->color = BLACK;

}

//通用旋转函数
/*
*theParent是item的父节点,item为被旋转的节点
*旋转可能性:
*左子树像向转,左子树向右转
*右子树像向转,右子树向右转
*/
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>
Cref<Comparable> RedBlackTree<Comparable>::find(const Comparable &x) {

	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>();
		}
	}

}

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->left != nullNode) {
		itr = itr->right;
	}
	return Cref<Comparable>(itr->element);

}

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;
	}

}

#endif

//
main.cpp

#include <iostream>

#include "RedBlackTree.h"

using namespace std;

int main(int argc, char** argv) {

	RedBlackTree<int> t(-99999);
	t.insert(50);
	t.insert(40);
	t.insert(30);

	return 0;

}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值