数据结构与算法(C语言版)__红黑树05

来源:互联网 发布:淘宝如何查看收藏宝贝 编辑:程序博客网 时间:2024/05/17 22:03

继续完善我们的insert函数
红黑树新插入的节点都是红色的。

新插入的节点X是内部孙子,双旋转
新插入的节点X是外部孙子,单旋转

还要处理有两个红色孩子的节点。
在头文件中加入Except.h和RedBlackTree.h在源文件中加入TestRedBlackTree.cpp

//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){}};#endif

下面是红黑树主要程序

//RedBlackTree.h//红黑树主要程序#ifndef RED_BLACK_TREE_H_#define RED_BLACK_TREE_H_#include"Except.h"template<class Comparable>class RedBlackTree;template<class Comparable>class RedBlackNode;template<class Comparable>class RedBlackTree{public:    RedBlackTree(const Comparable & negInf);//红黑树的构造函数    ~RedBlackTree();    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 * & k4)const;    void handleReorient(const Comparable & item);    RedBlackNode<Comparable>* rotate(const Comparable & item, Node *parent)const;//返回旋转以后的根};template<class Comparable>class RedBlackNode{//private:为了测试,临时变成publicpublic:    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;//横向移动    k1->right = k2;    k2 = k1;}template<class Comparable>void RedBlackTree<Comparable>::rotateWithRightChild(Node * & k1)const{    Node *k2 = k1->right;    k1->right = k2->left;    k2->left = k1;    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 * & k4)const{    rotateWithLeftChild(k4->right);    rotateWithRightChild(k4);}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;    }}#endif

下面是测试红黑树的程序,可以看到插入的第一个节点50不是根节点。

//TestRedBlackTree.cpp//测试红黑树#include<iostream>#include"RedBlackTree.h"using namespace std;int main(){    cout << "测试红黑树:" << endl;    const int NEG_INF = -99999;//负的无穷大,    RedBlackTree<int> t(NEG_INF);//创建一个空树,    t.insert(50);    t.insert(40);    t.insert(30);    t.insert(20);    t.insert(10);    cout << t.header->right->element << endl;    system("pause");    return 0;}

总结:今天我们把insert函数做好,算是把红黑树的最复杂的函数写出来,可以看到红黑树可以动态调整根节点。

0 0
原创粉丝点击