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

来源:互联网 发布:白狐小说系统源码 编辑:程序博客网 时间:2024/06/15 21:33
#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);elsereturn 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;}

0 0
原创粉丝点击