Advertisement
AlexFSmirnov

Red-Black tree

Apr 26th, 2018
165
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 12.66 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3.  
  4. using namespace std;
  5.  
  6.  
  7. struct TNode {
  8.     int color;      // 0 - black, 1 - red, 2 - double-black;
  9.     bool is_nil;    // Is nil?
  10.     int val;        // Node's value.
  11.     TNode *left;    // Left sub-tree.
  12.     TNode *right;   // Right sub-tree.
  13.     TNode *parent;  // Parent of the node.
  14. };
  15. class RBtree {
  16.     private:
  17.         TNode *root;
  18.  
  19.         TNode *new_node(int);
  20.         void set_node(TNode *, TNode *);
  21.         void check_nil(TNode *&);
  22.        
  23.         int get_color(TNode *);
  24.         void set_color(TNode *&, int);
  25.  
  26.         TNode *_find(TNode *, int);
  27.         TNode *_find_least(TNode *);
  28.         void rotate_left(TNode *);
  29.         void rotate_right(TNode *);
  30.  
  31.         void _insert(int, TNode *&, TNode *);
  32.         void insert_fix(TNode *);
  33.  
  34.         void _remove(TNode *&);
  35.         void remove_fix(TNode *);
  36.  
  37.     public:
  38.         RBtree() {
  39.             root = nullptr;
  40.         }
  41.  
  42.         TNode *find(int);
  43.         void insert(int);
  44.         void remove(int);
  45.         void print(TNode *root=nullptr, int offset=0);
  46. };
  47.  
  48. // Private functions {
  49. TNode *RBtree::new_node(int val) {
  50.     TNode *node = new TNode({1, 0, val, nullptr, nullptr, nullptr});
  51.     return node;
  52. }
  53. void RBtree::set_node(TNode *node, TNode *new_node) {
  54.     if (new_node != nullptr) {
  55.         new_node->parent = node->parent;
  56.     }
  57.     if (node->parent != nullptr) {
  58.         if (node == node->parent->left) {
  59.             node->parent->left = new_node;
  60.         } else {
  61.             node->parent->right = new_node;
  62.         }
  63.     } else {
  64.         this->root = new_node;
  65.     }
  66. }
  67. void RBtree::check_nil(TNode *&node) {
  68.     if (node->is_nil) {
  69.         if (node->parent != nullptr) {
  70.             if (node == node->parent->left) {
  71.                 node->parent->left = nullptr;
  72.             } else {
  73.                 node->parent->right = nullptr;
  74.             }
  75.         } else {
  76.             this->root = nullptr;
  77.         }
  78.         free(node);
  79.     }
  80. }
  81.  
  82. int RBtree::get_color(TNode *node) {
  83.     if (node == nullptr) {
  84.         return 0;
  85.     }
  86.     return node->color;
  87. }
  88. void RBtree::set_color(TNode *&node, int color) {
  89.     if (node != nullptr) {
  90.         node->color = color;
  91.     }
  92. }
  93.  
  94. TNode *RBtree::_find(TNode *root, int val) {
  95.     if (root == nullptr) {
  96.         return nullptr;
  97.     } else if (val == root->val) {
  98.         return root;
  99.     } else if (val < root->val) {
  100.         return _find(root->left, val);
  101.     } else {
  102.         return _find(root->right, val);
  103.     }
  104. }
  105. TNode *RBtree::_find_least(TNode *root) {
  106.     while (root->left != nullptr) {
  107.         root = root->left;
  108.     }
  109.     return root;
  110. }
  111. void RBtree::rotate_left(TNode *prev_root) {
  112.     TNode *new_root = prev_root->right;  
  113.  
  114.     prev_root->right = new_root->left;  
  115.     if (new_root->left != nullptr) {
  116.         new_root->left->parent = prev_root;
  117.     }
  118.     new_root->parent = prev_root->parent;
  119.  
  120.     if (prev_root->parent == nullptr) {
  121.         this->root = new_root;
  122.     } else if (prev_root == prev_root->parent->left) {
  123.         prev_root->parent->left = new_root;
  124.     } else {
  125.         prev_root->parent->right = new_root;
  126.     }
  127.  
  128.     new_root->left = prev_root;
  129.     prev_root->parent = new_root;
  130. }
  131. void RBtree::rotate_right(TNode *prev_root) {
  132.     TNode *new_root = prev_root->left;
  133.  
  134.     prev_root->left = new_root->right;
  135.     if (new_root->right != nullptr) {
  136.         new_root->right->parent = prev_root;
  137.     }
  138.     new_root->parent = prev_root->parent;
  139.  
  140.     if (prev_root->parent == nullptr) {
  141.         this->root = new_root;
  142.     } else if (prev_root == prev_root->parent->left) {
  143.         prev_root->parent->left = new_root;
  144.     } else {
  145.         prev_root->parent->right = new_root;
  146.     }
  147.  
  148.     new_root->right = prev_root;
  149.     prev_root->parent = new_root;
  150. }
  151.  
  152. void RBtree::_insert(int val, TNode *&root, TNode *parent) {
  153.     if (root == nullptr) {
  154.         root = new_node(val);
  155.         root->parent = parent;
  156.         insert_fix(root);
  157.         return;
  158.     }
  159.     if (val < root->val) {
  160.         _insert(val, root->left, root);
  161.     } else if (val > root->val) {
  162.         _insert(val, root->right, root);
  163.     }
  164. }
  165. void RBtree::insert_fix(TNode *root) {
  166.     // Case 0. Root is always black.
  167.     // Case 1. Root's uncle is red.
  168.     // Case 2. Root's uncle is black, triangle.
  169.     // Case 3. Root's uncle is black, line.
  170.  
  171.     while (root && get_color(root->parent) == 1) {  // While parent is RED.
  172.         // Root's parent is on the left side.
  173.         if (root->parent == root->parent->parent->left) {
  174.             TNode *uncle = root->parent->parent->right;
  175.             if (get_color(uncle) == 1) {             // Case 1. Uncle is RED.
  176.                 set_color(root->parent, 0);          // Case 1. Recolor parent.
  177.                 set_color(uncle, 0);                 // Case 1. Recolor uncle.
  178.                 set_color(root->parent->parent, 1);  // Case 1. Recolor granp.
  179.                 // Continue from grandparent, if exists.
  180.                 root = root->parent ? root->parent->parent : nullptr;
  181.             } else {
  182.                 if (root == root->parent->right) {   // Case 2. Triangle.
  183.                     root = root->parent;             // Case 2.
  184.                     rotate_left(root);               // Case 2.
  185.                 }
  186.                 set_color(root->parent, 0);          // Case 3. Line.
  187.                 set_color(root->parent->parent, 1);  // Case 3.
  188.                 rotate_right(root->parent->parent);  // Case 3. Rotate granp.
  189.             }
  190.         }
  191.         // Root's parent is on the right side.
  192.         else {  
  193.             TNode *uncle = root->parent->parent->left;
  194.             if (get_color(uncle) == 1) {             // Case 1. Uncle is RED.
  195.                 set_color(root->parent, 0);          // Case 1. Recolor parent.
  196.                 set_color(uncle, 0);                 // Case 1. Recolor uncle.
  197.                 set_color(root->parent->parent, 1);  // Case 1. Recolor granp.
  198.                 // Continue from grandparent, if exists.
  199.                 root = root->parent ? root->parent->parent : nullptr;
  200.             } else {
  201.                 if (root == root->parent->left) {    // Case 2. Triangle.
  202.                     root = root->parent;             // Case 2.
  203.                     rotate_right(root);              // Case 2.
  204.                 }
  205.                 set_color(root->parent, 0);          // Case 3. Line.
  206.                 set_color(root->parent->parent, 1);  // Case 3.
  207.                 rotate_left(root->parent->parent);   // Case 3. Rotate granp.
  208.             }
  209.         }
  210.     }
  211.     set_color(this->root, 0);
  212. }
  213.  
  214. void RBtree::_remove(TNode *&root) {
  215.     if (root->left && root->right) {                 // Both children
  216.         TNode *successor = _find_least(root->right);
  217.         root->val = successor->val;
  218.         _remove(successor);
  219.     }
  220.     else if (!root->left && !root->right) {          // Leaf
  221.         if (get_color(root) == 1) {                  // Root is red
  222.             set_node(root, nullptr);
  223.             free(root);
  224.         } else {                                     // Root is black
  225.             root->is_nil = 1;
  226.             root->color = 2;
  227.             remove_fix(root);
  228.         }
  229.     }
  230.     else if (root->left || root->right) {            // One child.
  231.         TNode *child;
  232.         if (root->left) {                            // Left child.
  233.             child = root->left;
  234.         } else {                                     // Right child.
  235.             child = root->right;
  236.         }
  237.  
  238.         set_node(root, child);
  239.         // Either root or it's child is red.
  240.         if (get_color(root) == 1 or get_color(child) == 1) {
  241.             set_color(child, 0);
  242.             free(root);
  243.         }
  244.         // Both root and it's child are black.
  245.         else {
  246.             set_color(child, 2);
  247.             remove_fix(child);
  248.         }
  249.     }
  250. }
  251. void RBtree::remove_fix(TNode *node) {
  252.     while (true) {
  253.         // Case 0. TERMINAL. Node is tree's root.
  254.         if (node->parent == nullptr) {
  255.             set_color(node, 0);
  256.             check_nil(node);
  257.             break;
  258.         }
  259.        
  260.         // The node is not root, so we can find it's sibling.
  261.         TNode *sib = nullptr;
  262.         bool node_side = 0;
  263.         if (node == node->parent->left) {
  264.             sib = node->parent->right;
  265.             node_side = 0;
  266.         } else {
  267.             sib = node->parent->left;
  268.             node_side = 1;
  269.         }
  270.  
  271.         // Case 1. Sibling is red.
  272.         if (get_color(sib) == 1) {
  273.             set_color(node->parent, 1);
  274.             set_color(sib, 0);
  275.             if (node_side == 0) {
  276.                 rotate_left(node->parent);
  277.             } else {
  278.                 rotate_right(node->parent);
  279.             }
  280.             continue;
  281.         }
  282.  
  283.         // Case 2. Sibling is black, sib's children are black.
  284.         if (!get_color(sib) &&
  285.                 !get_color(sib->left) && !get_color(sib->right)) {
  286.             set_color(sib, 1);
  287.             set_color(node, 0);
  288.             // Parent is red, terminal state.
  289.             if (get_color(node->parent) == 1) {
  290.                 set_color(node->parent, 0);
  291.                 check_nil(node);
  292.                 break;
  293.             }
  294.             // Parent is black. Moving double-black to it.
  295.             else {
  296.                 set_color(node->parent, 2);
  297.                 check_nil(node);
  298.                 node = node->parent;
  299.             }
  300.             continue;
  301.         }
  302.  
  303.         // Case 3. Sibling is black, sib-inner:red, sib-outer: black.
  304.         // Case 4. Sibling is black, sib-inner:---, sib-outer: red.
  305.         if (get_color(sib) == 0) {
  306.             if (node_side == 0) {  // Node is left child, sibling is right.
  307.                 // Case 3.
  308.                 if (get_color(sib->left) == 1 && get_color(sib->right) == 0) {
  309.                     set_color(sib, 1);
  310.                     set_color(sib->left, 0);
  311.                     rotate_right(sib);
  312.                 }
  313.                 // Case 4. TERMINAL.
  314.                 if (get_color(sib->right) == 1) {
  315.                     set_color(sib->right, 0);
  316.                     set_color(sib, get_color(sib->parent));
  317.                     set_color(sib->parent, 0);
  318.                     set_color(node, 0);
  319.                     check_nil(node);
  320.                     rotate_left(sib->parent);
  321.                     break;
  322.                 }
  323.             } else {               // Node is right child, sibling is left.
  324.                 // Case 3.
  325.                 if (get_color(sib->right) == 1 && get_color(sib->left) == 0) {
  326.                     set_color(sib, 1);
  327.                     set_color(sib->right, 0);
  328.                     rotate_left(sib);
  329.                 }
  330.                 // Case 4. TERMINAL.
  331.                 if (get_color(sib->left) == 1) {
  332.                     set_color(sib->left, 0);
  333.                     set_color(sib, get_color(sib->parent));
  334.                     set_color(sib->parent, 0);
  335.                     set_color(node, 0);
  336.                     check_nil(node);
  337.                     rotate_right(sib->parent);
  338.                     break;
  339.                 }
  340.             }
  341.         }
  342.     }
  343.     set_color(this->root, 0);
  344. }
  345. // }
  346.  
  347.  
  348. // Public functions {
  349. TNode *RBtree::find(int val) {
  350.     return _find(this->root, val);
  351. }
  352.  
  353. void RBtree::insert(int val) {
  354.     _insert(val, this->root, nullptr);
  355. }
  356.  
  357. void RBtree::remove(int val) {
  358.     TNode *node = find(val);
  359.     if (node != nullptr) {
  360.         _remove(node);
  361.     }
  362. }
  363.  
  364. void RBtree::print(TNode *root, int offset) {
  365.     if (root == nullptr && offset == 0) {
  366.         root = this->root;
  367.     }
  368.     if (root == nullptr) {
  369.         return;
  370.     }
  371.     this->print(root->right, offset + 1);
  372.  
  373.     for (int i = 0; i < offset; i++) cout << "     ";
  374.     if (root->color == 0) {
  375.         cout << "\033[1;34m";
  376.     } else if (root->color == 1) {
  377.         cout << "\033[1;31m";
  378.     } else if (root->color == 2) {
  379.         cout << "\033[1;30m";
  380.     }
  381.  
  382.     if (root->is_nil) {
  383.         cout << "N";
  384.     } else {
  385.         cout << root->val;
  386.     }
  387.  
  388.     cout << "\033[0m\n";
  389.        
  390.     this->print(root->left, offset + 1);
  391. }
  392. // }
  393.  
  394.  
  395. int main() {
  396.     RBtree tree;
  397.  
  398.  
  399.     vector<int> v = {8, 15, 23, 17, 2, 16, 7, 21, 22};
  400.     for (auto i : v) {
  401.         tree.insert(i);
  402.     }
  403.     tree.print();
  404.  
  405.  
  406.     int t, x;
  407.     while (1) {
  408.         cin >> t >> x;
  409.         if (t == 0) {
  410.             cout << "Inserting " << x << "...\n";
  411.             tree.insert(x);
  412.         } else {
  413.             cout << "Removing " << x << "...\n";
  414.             tree.remove(x);
  415.         }
  416.         cout << "----------------------------------------\n";
  417.         tree.print();
  418.         cout << "----------------------------------------\n\n\n";
  419.     }
  420.  
  421.  
  422.     return 0;
  423. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement