红黑树: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 = NULL, int 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() == 50) cout << "找到了最小的数!" << 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++实现的主要内容,如果未能解决你的问题,请参考以下文章