红黑树C++完整版

Posted 薛萌

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了红黑树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;


以上是关于红黑树C++完整版的主要内容,如果未能解决你的问题,请参考以下文章

红黑树插入与删除完整代码(dart语言实现)

二叉树与红黑树

删除红黑树的整个子树会保留其属性吗?

动画 | 什么是红黑树?

高阶数据结构(贰)——红黑树的基本概念和插入的实现

高阶数据结构(贰)——红黑树的基本概念和插入的实现