├── .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 | } --------------------------------------------------------------------------------