红黑树:C++实现

Posted Action and Think

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了红黑树:C++实现相关的知识,希望对你有一定的参考价值。

RedBlackTree.h

 1#ifndef RED_BLACK_TREE_H
2#define RED_BLACK_TREE_H
3#include "Except.h"
4#include "Wrapper.h"
5template <class Comparable>
6class RedBlackTree;

7template<class Comparable>
8class RedBlackNode;

9template<class Comparable>
10class RedBlackTree
11{

12public:
13    RedBlackTree(const Comparable & negInf);
14    ~RedBlackTree();
15    Cref<Comparable> find(const Comparable &x) const;//查找某个数
16    Cref<Comparable> findMin() const;//查找最小的数
17    Cref<Comparable> findMax() const;//查找最大的数
18    bool IsEmpty() const;//判断是否为空
19    void makeEmpty();//清空
20    enum {RED,BLACK};
21    void insert(const Comparable &x);//插入
22    typedef RedBlackNode<Comparable> Node;
23//private:
24public:
25    Node *header;//指向红黑树头的指针,负无穷大,伪根
26    Node *nullNode;
27    Node *current;//指向当前结点
28    Node *parent;//指向当前结点的父结点
29    Node *grand; //祖父结点
30    Node *great; //曾祖父结点
31    void reclaimMemory(Node *t)const;
32    void rotateWithLeftChild(Node * &k2) const;//以k2为标准旋转,向右旋转
33    void rotateWithRightChild(Node * &k1) const;//向左旋转
34    void doubleRotateWithLeftChild(Node * &k3) const;//双旋转
35    void doubleRotateWithRightChild(Node * &k1) const;//双旋转
36    void handleReorient(const Comparable & item);
37    RedBlackNode<Comparable> * rotate(const Comparable &item, Node *parent) const;//旋转函数
38};
39template<class Comparable>
40class RedBlackNode
41{

42public:
43    Comparable   element;
44    RedBlackNode *left;
45    RedBlackNode *right;
46    int          color;
47    RedBlackNode(const Comparable & theElement = Comparable(),
48        RedBlackNode *lt =NULL, RedBlackNode *rt = NULLint c = RedBlackTree<Comparable>::BLACK)
49        :element(theElement),left(lt),right(rt),color(c){};
50    friend class RedBlackTree<Comparable>;
51};
52template<class Comparable>
53RedBlackTree<Comparable>:
:RedBlackTree(const Comparable & negInf)
54{
55    nullNode = new Node();
56    nullNode->left = nullNode->right = nullNode;
57    header = new Node(negInf);
58    header->left = header->right = nullNode;
59}
60template<class Comparable>
61RedBlackTree<Comparable>:
:~RedBlackTree()
62{
63    makeEmpty();
64    delete nullNode;
65    delete header;
66}
67template<class Comparable>
68void RedBlackTree<Comparable>:
:insert(const Comparable &x)
69{
70    current = parent = grand = header;
71    nullNode->element = x;
72    while(current->element != x)//查找新的结点插入的位置
73    {
74        great = grand; grand = parent; parent = current;
75        current = x < current->element ? current->left :current->right;
76        if(current->left->color == RED && current->right->color == RED)
77            handleReorient(x);
78    }
79    if(current != nullNode)
80        throw DuplicateItemException();
81    current = new Node(x,nullNode,nullNode);
82    if(x<parent->element)
83        parent->left = current;
84    else
85        parent->right = current;
86    //自动平衡,变为红黑树
87    handleReorient(x);
88}
89template <class Comparable>
90void RedBlackTree<Comparable>:
:rotateWithLeftChild(Node * &k2) const//向右转
91{
92    Node *k1 = k2->left;
93    k2->left = k1->right;
94    k1->right = k2;
95    k2 = k1;
96}
97template <class Comparable>
98void RedBlackTree<Comparable>:
:rotateWithRightChild(Node * &k1) const
99{
100    Node *k2 = k1->right;
101    k1->right = k2->left;
102    k2->left = k1;
103    k1 = k2;
104}
105template <class Comparable>
106void RedBlackTree<Comparable>:
:doubleRotateWithLeftChild(Node * &k3) const
107{
108    rotateWithRightChild(k3->left);
109    rotateWithLeftChild(k3);
110}
111template <class Comparable>
112void RedBlackTree<Comparable>:
:doubleRotateWithRightChild(Node * &k1) const
113{
114    rotateWithLeftChild(k1->right);
115    rotateWithRightChild(k1);
116}
117template<class Comparable>
118void RedBlackTree<Comparable>:
:handleReorient(const Comparable & item)
119{
120    //变色,一个节点有两个孩子为红时,把该节点变红
121    current->color = RED;
122    current->left->color = BLACK;
123    current->right->color = BLACK;
124    if(parent->color == RED)
125    {
126        grand->color = RED;
127        if(item < grand->element != item < parent->element)//内部孙子节点
128            parent = rotate(item,grand);
129        current = rotate(item,great);
130        current->color = BLACK;
131    }
132    header->right->color = BLACK;
133    //单旋转
134    //双旋转
135}
136template < class Comparable>
137RedBlackNode<Comparable>* RedBlackTree<Comparable>:
:rotate(const Comparable &item, Node *theParent) const
138{
139    if(item <theParent->element)
140    {
141        item < theParent->left->element ? 
142            rotateWithLeftChild(theParent->left):
143        rotateWithRightChild(theParent->left);
144        return theParent->left;
145    }
146    else
147    {
148        item < theParent->right->element ? 
149            rotateWithLeftChild(theParent->right):
150        rotateWithRightChild(theParent->right);
151        return theParent->right;
152    }
153}
154template<class Comparable>
155bool RedBlackTree<Comparable>:
:IsEmpty() const
156{
157    return header->right == nullNode;
158}
159template<class Comparable>
160void RedBlackTree<Comparable>:
:makeEmpty()
161{
162    reclaimMemory(header->right);
163    header->right = nullNode;
164}
165template < class Comparable>
166void RedBlackTree<Comparable>:
:reclaimMemory(Node* t) const
167{
168    if(t!=t->left)
169    {
170        reclaimMemory(t->left);
171        reclaimMemory(t->right);
172        delete t;
173    }
174}
175template<class Comparable>
176Cref<Comparable> RedBlackTree<Comparable>:
:findMin() const
177{
178    if(IsEmpty())
179        return Cref<Comparable>();
180    Node *itr = header->right;
181    while(itr->left !=nullNode)
182    {
183        itr = itr->left;
184    }
185    return Cref<Comparable>(itr->element);
186};
187template<class Comparable>
188Cref<Comparable> RedBlackTree<Comparable>:
:findMax() const
189{
190    if(IsEmpty())
191        return Cref<Comparable>();
192     Node *itr = header->right;
193    while(itr->right !=nullNode)
194    {
195        itr = itr->right;
196    }
197    return Cref<Comparable>(itr->element);
198}
199template<class Comparable>
200Cref<Comparable> RedBlackTree<Comparable>:
:find(const Comparable &x) const
201{
202    nullNode->element = x;
203    Node *curr = header->right;
204    for(;;)
205    {
206        if(x < curr->element)
207            curr = curr->left;
208        else if(x> curr->element)
209            curr = curr->right;
210        else if (curr != nullNode)
211            return Cref<Comparable>(curr->element);
212        else
213            return Cref<Comparable>();
214    }
215}
216#endif

Except.h

 1#ifndef EXCEPT_H
2#define EXCEPT_H
3#include<string>
4using namespace std;
5class DSException
6{

7public:
8    DSException(const string &msg = ""):message(msg){}
9    virtual ~DSException() {}
10    virtual string toString() const
11    
{
12        return "Exception" + string(": ") + what();
13    }
14    virtual string what() const
15    
{
16        return message;
17    }
18private:
19    string message;
20};
21class DuplicateItemException : public DSException
22{
23public:
24    DuplicateItemException(const string &msg = ""):DSException(msg){}
25};
26class NullPointerException:public DSException
27{
28public:
29    NullPointerException(const string & msg = ""):DSException(msg)
30    {}
31};
32#endif

Wrapper.h

 1#ifndef WRAPPER_H
2#define WRAPPER_H
3#include "Except.h"
4template <class Object>
5class Cref
6{

7public:
8    Cref():obj(NULL) {}
9    explicit Cref(const Object &x):obj(&x){}
10    const Object & get() const
11    
{
12        if(isNull()) throw NullPointerException();
13        else return *obj;
14    }
15    bool isNull() const
16    
{
17        return obj == NULL;
18    }
19private:
20    const Object *obj;
21};
22#endif

测试

 1#include<iostream>
2#include "RedBlackTree.h"
3using namespace std;
4int main()
5
{
6    const int NEG_INF = -99999;//负无穷大
7    RedBlackTree<int> t(NEG_INF);
8    //t.insert(30);
9    //t.insert(15);
10    //t.insert(70);
11    //t.insert(20);
12    //cout << t.header->right->element <<endl;
13    //cout << t.header->right->left->element << endl;
14    //cout << t.header->right->right->element << endl;
15    //cout << t.header->right->left->right->element << endl;
16    //cout << "向右转" << endl;
17    //t.rotateWithLeftChild(t.header->right);
18    //cout << t.header->right->element <<endl;
19    //cout << t.header->right->right->left->element << endl;
20    //cout << "向左转" << endl;
21    //t.rotateWithRightChild(t.header->right);
22    //cout << t.header->right->element <<endl;
23    //cout << t.header->right->left->element << endl;
24    //cout << t.header->right->right->element << endl;
25    //cout << t.header->right->left->right->element << endl;
26    //t.insert(12);
27    //t.insert(16);
28    //t.insert(8);
29    //t.insert(10);
30    //t.insert(4);
31    //t.insert(14);
32    //t.insert(2);
33    //t.insert(6);
34    //t.insert(5);
35    //cout << t.header->right->element <<endl;
36    //cout << t.header->right->left->element << endl;
37    //t.doubleRotateWithLeftChild(t.header->right->left);
38    //cout << t.header->right->left->element << endl;
39    t.insert(50);
40    t.insert(40);
41    t.insert(30);
42    cout << t.header->right->element << endl;
43    if(!t.IsEmpty()) cout << "红黑树不是空的!" << endl;
44    t.makeEmpty();
45    if(t.IsEmpty()) cout << "红黑树是空的!" << endl;
46    t.insert(200);
47    t.insert(100);
48    t.insert(90);
49    t.insert(50);
50    t.insert(80);
51    t.insert(70);
52    t.insert(60);
53    if(t.findMin().get() == 50cout << "找到了最小的数!" << endl;
54    cout << "最大的:" << t.findMax().get() << endl;
55    Cref<int> r=t.find(60);
56    if(r.isNull()) cout << "没找到!"<<endl;
57    else cout<< r.get() << endl;
58    cout << "OK" << endl;
59    return 0;
60}


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

C++红黑树

C++红黑树

C++红黑树

红黑树特性和实现详解——C++进阶数据结构

红黑树特性和实现详解——C++进阶数据结构

红黑树特性和实现详解——C++进阶数据结构