红黑树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++完整版的主要内容,如果未能解决你的问题,请参考以下文章