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