├── .idea
├── .name
├── Red-Black-Tree.iml
├── misc.xml
├── vcs.xml
└── modules.xml
├── CMakeLists.txt
├── main.cpp
├── RBTree.h
└── RBTree.cpp
/.idea/.name:
--------------------------------------------------------------------------------
1 | Red_Black_Tree
--------------------------------------------------------------------------------
/.idea/Red-Black-Tree.iml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.5)
2 | project(Red_Black_Tree)
3 |
4 | set(CMAKE_CXX_STANDARD 11)
5 |
6 | set(SOURCE_FILES main.cpp RBTree.cpp RBTree.h)
7 | add_executable(Red_Black_Tree ${SOURCE_FILES})
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/main.cpp:
--------------------------------------------------------------------------------
1 | // Driver Program for Red Black Tree
2 |
3 | #include
4 | #include "RBTree.h"
5 | using namespace std;
6 |
7 | int main() {
8 | int data;
9 | RBTree rbTree1, rbTree2;
10 |
11 | cin >> data;
12 | while (data != 0)
13 | {
14 | rbTree1.insertValue(data);
15 | cin >> data;
16 | }
17 |
18 | rbTree1.preorder();
19 |
20 | cin >> data;
21 | while (data != 0)
22 | {
23 | rbTree2.insertValue(data);
24 | cin >> data;
25 | }
26 |
27 | rbTree2.preorder();
28 |
29 | rbTree1.merge(rbTree2);
30 | rbTree1.preorder();
31 |
32 | return 0;
33 | }
--------------------------------------------------------------------------------
/RBTree.h:
--------------------------------------------------------------------------------
1 | //
2 | // Red Black Tree Definition
3 | //
4 |
5 | #ifndef RED_BLACK_TREE_RBTREE_H
6 | #define RED_BLACK_TREE_RBTREE_H
7 |
8 | enum Color {RED, BLACK, DOUBLE_BLACK};
9 |
10 | struct Node
11 | {
12 | int data;
13 | int color;
14 | Node *left, *right, *parent;
15 |
16 | explicit Node(int);
17 | };
18 |
19 | class RBTree
20 | {
21 | private:
22 | Node *root;
23 | protected:
24 | void rotateLeft(Node *&);
25 | void rotateRight(Node *&);
26 | void fixInsertRBTree(Node *&);
27 | void fixDeleteRBTree(Node *&);
28 | void inorderBST(Node *&);
29 | void preorderBST(Node *&);
30 | int getColor(Node *&);
31 | void setColor(Node *&, int);
32 | Node *minValueNode(Node *&);
33 | Node *maxValueNode(Node *&);
34 | Node* insertBST(Node *&, Node *&);
35 | Node* deleteBST(Node *&, int);
36 | int getBlackHeight(Node *);
37 | public:
38 | RBTree();
39 | void insertValue(int);
40 | void deleteValue(int);
41 | void merge(RBTree);
42 | void inorder();
43 | void preorder();
44 | };
45 |
46 |
47 | #endif //RED_BLACK_TREE_RBTREE_H
48 |
--------------------------------------------------------------------------------
/RBTree.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Red Black Tree Implementation
3 | //
4 | #include
5 | #include "RBTree.h"
6 | using namespace std;
7 |
8 | Node::Node(int data) {
9 | this->data = data;
10 | color = RED;
11 | left = right = parent = nullptr;
12 | }
13 |
14 | RBTree::RBTree() {
15 | root = nullptr;
16 | }
17 |
18 | int RBTree::getColor(Node *&node) {
19 | if (node == nullptr)
20 | return BLACK;
21 |
22 | return node->color;
23 | }
24 |
25 | void RBTree::setColor(Node *&node, int color) {
26 | if (node == nullptr)
27 | return;
28 |
29 | node->color = color;
30 | }
31 |
32 | Node* RBTree::insertBST(Node *&root, Node *&ptr) {
33 | if (root == nullptr)
34 | return ptr;
35 |
36 | if (ptr->data < root->data) {
37 | root->left = insertBST(root->left, ptr);
38 | root->left->parent = root;
39 | } else if (ptr->data > root->data) {
40 | root->right = insertBST(root->right, ptr);
41 | root->right->parent = root;
42 | }
43 |
44 | return root;
45 | }
46 |
47 | void RBTree::insertValue(int n) {
48 | Node *node = new Node(n);
49 | root = insertBST(root, node);
50 | fixInsertRBTree(node);
51 | }
52 |
53 | void RBTree::rotateLeft(Node *&ptr) {
54 | Node *right_child = ptr->right;
55 | ptr->right = right_child->left;
56 |
57 | if (ptr->right != nullptr)
58 | ptr->right->parent = ptr;
59 |
60 | right_child->parent = ptr->parent;
61 |
62 | if (ptr->parent == nullptr)
63 | root = right_child;
64 | else if (ptr == ptr->parent->left)
65 | ptr->parent->left = right_child;
66 | else
67 | ptr->parent->right = right_child;
68 |
69 | right_child->left = ptr;
70 | ptr->parent = right_child;
71 | }
72 |
73 | void RBTree::rotateRight(Node *&ptr) {
74 | Node *left_child = ptr->left;
75 | ptr->left = left_child->right;
76 |
77 | if (ptr->left != nullptr)
78 | ptr->left->parent = ptr;
79 |
80 | left_child->parent = ptr->parent;
81 |
82 | if (ptr->parent == nullptr)
83 | root = left_child;
84 | else if (ptr == ptr->parent->left)
85 | ptr->parent->left = left_child;
86 | else
87 | ptr->parent->right = left_child;
88 |
89 | left_child->right = ptr;
90 | ptr->parent = left_child;
91 | }
92 |
93 | void RBTree::fixInsertRBTree(Node *&ptr) {
94 | Node *parent = nullptr;
95 | Node *grandparent = nullptr;
96 | while (ptr != root && getColor(ptr) == RED && getColor(ptr->parent) == RED) {
97 | parent = ptr->parent;
98 | grandparent = parent->parent;
99 | if (parent == grandparent->left) {
100 | Node *uncle = grandparent->right;
101 | if (getColor(uncle) == RED) {
102 | setColor(uncle, BLACK);
103 | setColor(parent, BLACK);
104 | setColor(grandparent, RED);
105 | ptr = grandparent;
106 | } else {
107 | if (ptr == parent->right) {
108 | rotateLeft(parent);
109 | ptr = parent;
110 | parent = ptr->parent;
111 | }
112 | rotateRight(grandparent);
113 | swap(parent->color, grandparent->color);
114 | ptr = parent;
115 | }
116 | } else {
117 | Node *uncle = grandparent->left;
118 | if (getColor(uncle) == RED) {
119 | setColor(uncle, BLACK);
120 | setColor(parent, BLACK);
121 | setColor(grandparent, RED);
122 | ptr = grandparent;
123 | } else {
124 | if (ptr == parent->left) {
125 | rotateRight(parent);
126 | ptr = parent;
127 | parent = ptr->parent;
128 | }
129 | rotateLeft(grandparent);
130 | swap(parent->color, grandparent->color);
131 | ptr = parent;
132 | }
133 | }
134 | }
135 | setColor(root, BLACK);
136 | }
137 |
138 | void RBTree::fixDeleteRBTree(Node *&node) {
139 | if (node == nullptr)
140 | return;
141 |
142 | if (node == root) {
143 | root = nullptr;
144 | return;
145 | }
146 |
147 | if (getColor(node) == RED || getColor(node->left) == RED || getColor(node->right) == RED) {
148 | Node *child = node->left != nullptr ? node->left : node->right;
149 |
150 | if (node == node->parent->left) {
151 | node->parent->left = child;
152 | if (child != nullptr)
153 | child->parent = node->parent;
154 | setColor(child, BLACK);
155 | delete (node);
156 | } else {
157 | node->parent->right = child;
158 | if (child != nullptr)
159 | child->parent = node->parent;
160 | setColor(child, BLACK);
161 | delete (node);
162 | }
163 | } else {
164 | Node *sibling = nullptr;
165 | Node *parent = nullptr;
166 | Node *ptr = node;
167 | setColor(ptr, DOUBLE_BLACK);
168 | while (ptr != root && getColor(ptr) == DOUBLE_BLACK) {
169 | parent = ptr->parent;
170 | if (ptr == parent->left) {
171 | sibling = parent->right;
172 | if (getColor(sibling) == RED) {
173 | setColor(sibling, BLACK);
174 | setColor(parent, RED);
175 | rotateLeft(parent);
176 | } else {
177 | if (getColor(sibling->left) == BLACK && getColor(sibling->right) == BLACK) {
178 | setColor(sibling, RED);
179 | if(getColor(parent) == RED)
180 | setColor(parent, BLACK);
181 | else
182 | setColor(parent, DOUBLE_BLACK);
183 | ptr = parent;
184 | } else {
185 | if (getColor(sibling->right) == BLACK) {
186 | setColor(sibling->left, BLACK);
187 | setColor(sibling, RED);
188 | rotateRight(sibling);
189 | sibling = parent->right;
190 | }
191 | setColor(sibling, parent->color);
192 | setColor(parent, BLACK);
193 | setColor(sibling->right, BLACK);
194 | rotateLeft(parent);
195 | break;
196 | }
197 | }
198 | } else {
199 | sibling = parent->left;
200 | if (getColor(sibling) == RED) {
201 | setColor(sibling, BLACK);
202 | setColor(parent, RED);
203 | rotateRight(parent);
204 | } else {
205 | if (getColor(sibling->left) == BLACK && getColor(sibling->right) == BLACK) {
206 | setColor(sibling, RED);
207 | if (getColor(parent) == RED)
208 | setColor(parent, BLACK);
209 | else
210 | setColor(parent, DOUBLE_BLACK);
211 | ptr = parent;
212 | } else {
213 | if (getColor(sibling->left) == BLACK) {
214 | setColor(sibling->right, BLACK);
215 | setColor(sibling, RED);
216 | rotateLeft(sibling);
217 | sibling = parent->left;
218 | }
219 | setColor(sibling, parent->color);
220 | setColor(parent, BLACK);
221 | setColor(sibling->left, BLACK);
222 | rotateRight(parent);
223 | break;
224 | }
225 | }
226 | }
227 | }
228 | if (node == node->parent->left)
229 | node->parent->left = nullptr;
230 | else
231 | node->parent->right = nullptr;
232 | delete(node);
233 | setColor(root, BLACK);
234 | }
235 | }
236 |
237 | Node* RBTree::deleteBST(Node *&root, int data) {
238 | if (root == nullptr)
239 | return root;
240 |
241 | if (data < root->data)
242 | return deleteBST(root->left, data);
243 |
244 | if (data > root->data)
245 | return deleteBST(root->right, data);
246 |
247 | if (root->left == nullptr || root->right == nullptr)
248 | return root;
249 |
250 | Node *temp = minValueNode(root->right);
251 | root->data = temp->data;
252 | return deleteBST(root->right, temp->data);
253 | }
254 |
255 | void RBTree::deleteValue(int data) {
256 | Node *node = deleteBST(root, data);
257 | fixDeleteRBTree(node);
258 | }
259 |
260 | void RBTree::inorderBST(Node *&ptr) {
261 | if (ptr == nullptr)
262 | return;
263 |
264 | inorderBST(ptr->left);
265 | cout << ptr->data << " " << ptr->color << endl;
266 | inorderBST(ptr->right);
267 | }
268 |
269 | void RBTree::inorder() {
270 | inorderBST(root);
271 | }
272 |
273 | void RBTree::preorderBST(Node *&ptr) {
274 | if (ptr == nullptr)
275 | return;
276 |
277 | cout << ptr->data << " " << ptr->color << endl;
278 | preorderBST(ptr->left);
279 | preorderBST(ptr->right);
280 | }
281 |
282 | void RBTree::preorder() {
283 | preorderBST(root);
284 | cout << "-------" << endl;
285 | }
286 |
287 | Node *RBTree::minValueNode(Node *&node) {
288 |
289 | Node *ptr = node;
290 |
291 | while (ptr->left != nullptr)
292 | ptr = ptr->left;
293 |
294 | return ptr;
295 | }
296 |
297 | Node* RBTree::maxValueNode(Node *&node) {
298 | Node *ptr = node;
299 |
300 | while (ptr->right != nullptr)
301 | ptr = ptr->right;
302 |
303 | return ptr;
304 | }
305 |
306 | int RBTree::getBlackHeight(Node *node) {
307 | int blackheight = 0;
308 | while (node != nullptr) {
309 | if (getColor(node) == BLACK)
310 | blackheight++;
311 | node = node->left;
312 | }
313 | return blackheight;
314 | }
315 |
316 | // Test case 1 : 5 2 9 1 6 8 0 20 30 35 40 50 0
317 | // Test case 2 : 3 0 5 0
318 | // Test case 3 : 2 1 3 0 8 9 4 5 0
319 |
320 | void RBTree::merge(RBTree rbTree2) {
321 | int temp;
322 | Node *c, *temp_ptr;
323 | Node *root1 = root;
324 | Node *root2 = rbTree2.root;
325 | int initialblackheight1 = getBlackHeight(root1);
326 | int initialblackheight2 = getBlackHeight(root2);
327 | if (initialblackheight1 > initialblackheight2) {
328 | c = maxValueNode(root1);
329 | temp = c->data;
330 | deleteValue(c->data);
331 | root1 = root;
332 | }
333 | else if (initialblackheight2 > initialblackheight1) {
334 | c = minValueNode(root2);
335 | temp = c->data;
336 | rbTree2.deleteValue(c->data);
337 | root2 = rbTree2.root;
338 | }
339 | else {
340 | c = minValueNode(root2);
341 | temp = c->data;
342 | rbTree2.deleteValue(c->data);
343 | root2 = rbTree2.root;
344 | if (initialblackheight1 != getBlackHeight(root2)) {
345 | rbTree2.insertValue(c->data);
346 | root2 = rbTree2.root;
347 | c = maxValueNode(root1);
348 | temp = c->data;
349 | deleteValue(c->data);
350 | root1 = root;
351 | }
352 | }
353 | setColor(c,RED);
354 | int finalblackheight1 = getBlackHeight(root1);
355 | int finalblackheight2 = getBlackHeight(root2);
356 | if (finalblackheight1 == finalblackheight2) {
357 | c->left = root1;
358 | root1->parent = c;
359 | c->right = root2;
360 | root2->parent = c;
361 | setColor(c,BLACK);
362 | c->data = temp;
363 | root = c;
364 | }
365 | else if (finalblackheight2 > finalblackheight1) {
366 | Node *ptr = root2;
367 | while (finalblackheight1 != getBlackHeight(ptr)) {
368 | temp_ptr = ptr;
369 | ptr = ptr->left;
370 | }
371 | Node *ptr_parent;
372 | if (ptr == nullptr)
373 | ptr_parent = temp_ptr;
374 | else
375 | ptr_parent = ptr->parent;
376 | c->left = root1;
377 | if (root1 != nullptr)
378 | root1->parent = c;
379 | c->right = ptr;
380 | if (ptr != nullptr)
381 | ptr->parent = c;
382 | ptr_parent->left = c;
383 | c->parent = ptr_parent;
384 | if (getColor(ptr_parent) == RED) {
385 | fixInsertRBTree(c);
386 | }
387 | else if (getColor(ptr) == RED){
388 | fixInsertRBTree(ptr);
389 | }
390 | c->data = temp;
391 | root = root2;
392 | }
393 | else {
394 | Node *ptr = root1;
395 | while (finalblackheight2 != getBlackHeight(ptr)) {
396 | ptr = ptr->right;
397 | }
398 | Node *ptr_parent = ptr->parent;
399 | c->right = root2;
400 | root2->parent = c;
401 | c->left = ptr;
402 | ptr->parent = c;
403 | ptr_parent->right = c;
404 | c->parent = ptr_parent;
405 | if (getColor(ptr_parent) == RED) {
406 | fixInsertRBTree(c);
407 | }
408 | else if (getColor(ptr) == RED) {
409 | fixInsertRBTree(ptr);
410 | }
411 | c->data = temp;
412 | root = root1;
413 | }
414 | return;
415 | }
--------------------------------------------------------------------------------