Advertisement
Guest User

Untitled

a guest
Jun 25th, 2019
102
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 19.80 KB | None | 0 0
  1. #pragma once
  2. #include <iostream>
  3. #include <stdexcept>
  4.  
  5. using namespace std;
  6.  
  7. template<class T, typename T1>
  8. class Tree
  9. {
  10.     class Node
  11.     {
  12.     public:
  13.         Node* parent; //parent node
  14.         Node* left, *right; //left and right child node
  15.         int color; //color red = 1, black = 0
  16.         T data; //data
  17.         T1 key; //key
  18.         Node(T data_1, T1 key_1, Node* par_1, int color_1 = 1) : parent(par_1), left(nullptr), right(nullptr), color(color_1), data(data_1), key(key_1) {}
  19.     };
  20.     Node* root; //root
  21.     void RotateLeft(Node* node); //left rotation
  22.     void RotateRight(Node* node); //right rotation
  23.     void balancingAfterInsert(Node* new_elem, Node* father, Node* gr_father); //balancing after inserting a new item
  24.     bool isRightChild(Node* node); // is Right child
  25.     void GoToMaxLeft(Node* node); //looking for the maximum node from the left subtree (for remove)
  26.     void balancingAfterDelete(Node* son, Node* nodePar, Node* uncle); //recursive method for fix up changes after node removing
  27.     void DeleteRed(Node* node); //delete red node
  28.     void DeleteBlack(Node* node); //delete black node
  29. public:
  30.     Tree() : root(nullptr) {} //map constructor
  31.     ~Tree() { clear(root); } //map destructor
  32.     void insert(T data_n, T1 key_n); //inserting node
  33.     void clear(Node* ptr); //recursive delete map
  34.     void get_keys(Node* ptr); //returns a list of keys
  35.     void get_values(Node* ptr); //returns a list of data
  36.     void remove(T1 key_n); //remove node by the key
  37.     friend ostream& operator << (ostream& output_stream, Node* pointer) //output statement overload for node pointer
  38.     {
  39.         if (pointer != nullptr) { //if pointer exists
  40.             output_stream << "Data feild: " << pointer->data << endl; //output to stream date field
  41.             output_stream << "Key: " << pointer->key << endl; //output to stream key field
  42.             output_stream << "Node color: " << (pointer->color ? "red" : "black") << endl; //output to stream color field
  43.         }
  44.         else //if pointer is nullptr
  45.             output_stream << "Couldn't find node with such index!" << endl;
  46.         return output_stream; //return output stream
  47.     }
  48.  
  49.     Node* find(T1 key_n) //finds a node by key
  50.     {
  51.         Node* temp = root; //make new pointer on root
  52.         if (temp != nullptr) { //if tree exists
  53.                                //cycle for search temp with such key
  54.             while ((temp->right != nullptr && key_n > temp->key) || (temp->left != nullptr && key_n < temp->key)) {
  55.                 key_n > temp->key ? temp = temp->right : temp = temp->left;
  56.             }
  57.             if (temp->key == key_n) //if the keys match
  58.                 return temp; //return pointer to node
  59.         }
  60.         return nullptr; //if the tree doesn't exist or the node with such a key isn't found, returns nullptr
  61.     }
  62.  
  63.     Node* GetRoot() { //method for getting the root of a tree
  64.         return(root); //returns the pointer to the root
  65.     }
  66. };
  67.  
  68. template<class T, typename T1>
  69. bool Tree<T, T1>::isRightChild(Node* node) { //determines whether the node is a left or right child
  70.     return(node->parent->right == node); //if the node is right, then output true
  71. }
  72.  
  73. template<class T, typename T1>
  74. void Tree<T, T1>::RotateLeft(Node* node) //left rotation
  75. {
  76.     Node* node_right = node->right; //writes the right child of node
  77.     bool ifRoot = (node == root ? true : false); //is the node root?
  78.     if (!ifRoot) { //if the node isn't root
  79.         if (isRightChild(node)) //if the node is right, then
  80.             node->parent->right = node_right; //the right son of the node becomes the son of the father of the node
  81.         else
  82.             node->parent->left = node_right; //the right son of the node becomes the son of the father of the node
  83.     }
  84.     node_right->parent = node->parent; //do the parent node of his son his father
  85.     node->right = node_right->left; //do the right son of the node left son of his son
  86.     if (node_right->left != nullptr) //if the node grand son isn't a nullptr
  87.         node_right->left->parent = node; //create a connection between node and node_right left son
  88.     node_right->left = node; //create a connection between node and node_right
  89.     node->parent = node_right; //node_right is the node parent now
  90.     if (ifRoot) //if node is root
  91.         root = node_right; //make new root node_right
  92. }
  93.  
  94. template<class T, typename T1>
  95. void Tree<T, T1>::RotateRight(Node* node) //right rotation
  96. {
  97.     Node* node_left = node->left; //writes the left child of node
  98.     bool ifRoot = (node == root ? true : false); //is the node root?
  99.     if (!ifRoot) { //if the node isn't root
  100.         if (isRightChild(node)) //if the node is right, then
  101.             node->parent->right = node_left;  //the left son of the node becomes the son of the father of the node
  102.         else
  103.             node->parent->left = node_left; //the left son of the node becomes the son of the father of the node
  104.     }
  105.     node_left->parent = node->parent; //do the parent node of his son his father
  106.     node->left = node_left->right; //do the left son of the node right son of his son
  107.     if (node_left->right != nullptr) //if the node grand son isn't a nullptr
  108.         node_left->right->parent = node; //create a connection between node and node_left right son
  109.     node_left->right = node; //create a connection between node and node_left
  110.     node->parent = node_left; //node_left is the node parent now
  111.     if (ifRoot) //if node is root
  112.         root = node_left; //make new root node_left
  113. }
  114.  
  115. template<class T, typename T1>
  116. void Tree<T, T1>::balancingAfterInsert(Node* new_elem, Node* father, Node* gr_father) //balancing after inserting a new item
  117. {
  118.     if (isRightChild(father)) { //if the new node father is the right son
  119.         if (gr_father->left != nullptr && gr_father->left->color == 1) { //if the uncle of new node exists and his color is red
  120.             father->color = 0; //recolor father in black
  121.             gr_father->left->color = 0; //recolor uncle in black
  122.             if (gr_father != root) { //grand father isn't a root
  123.                 gr_father->color =1; //recolor grand father in red
  124.                 if (gr_father->parent->color == 1) //if uncle color is red
  125.                     balancingAfterInsert(gr_father, gr_father->parent, gr_father->parent->parent); //call balancing for grandfather, grand-grand father and grand-grand-grand father
  126.             }
  127.         }
  128.         else { //if uncle is nullptr or uncle color is black
  129.             if (isRightChild(new_elem)) { //if the new element is the right son
  130.                 RotateLeft(gr_father); //call left rotation of grand father
  131.                 father->color = 0; //recolor father in black
  132.                 gr_father->color =1; //recolor grandfather in red  
  133.             }
  134.             else { //if the new element is the left son
  135.                 RotateRight(father); //call right rotation of father
  136.                 balancingAfterInsert(father, new_elem, gr_father);
  137.             }
  138.         }
  139.     }
  140.     else { //if the new node father is the left son
  141.         if (gr_father->right != nullptr && gr_father->right->color == 1) { //if the uncle of new node exists and his color is red
  142.             father->color = 0; //recolor father in black
  143.             gr_father->right->color = 0; //recolor uncle in black
  144.             if (gr_father != root) { //grand father isn't a root
  145.                 gr_father->color =1; //recolor grand father in red
  146.                 if (gr_father->parent->color == 1) //if uncle color is red
  147.                     balancingAfterInsert(gr_father, gr_father->parent, gr_father->parent->parent); //call balancing for grandfather, grand-grand father and grand-grand-grand father
  148.             }
  149.         }
  150.         else { //if uncle is nullptr or uncle color is black
  151.             if (isRightChild(new_elem)) { //if the new element is the right son
  152.                 RotateLeft(father); //call left rotation of father
  153.                 balancingAfterInsert(father, new_elem, gr_father); //call balancing for father, new element and grandfather
  154.             }
  155.             else { //if the new element is the left son
  156.                 RotateRight(gr_father); //call the right rotation of the grandfather
  157.                 father->color = 0; //recolor father in black
  158.                 gr_father->color =1; //recolor grandfather in red
  159.             }
  160.         }
  161.     }
  162. }
  163.  
  164. template<class T, typename T1>
  165. void Tree<T, T1>::insert(T data_n, T1 key_n) //adding new item
  166. {
  167.     Node* temp = root, *new_node = nullptr; //make a new pointer to root and null pointer new_node
  168.     if (temp == nullptr) //if root is nullptr
  169.         root = new Node(data_n, key_n, nullptr, 0); //make a new element of the root
  170.     else {
  171.         //until we find a place to insert
  172.         while ((temp->right != nullptr && key_n >= temp->key) || (temp->left != nullptr && key_n < temp->key)) {
  173.             key_n < temp->key ? temp = temp->left : temp = temp->right; //depending on the key go to the left or right branch
  174.         }
  175.         if (key_n > temp->key) { //if key of new node bigger than previous node key
  176.             temp->right = new Node(data_n, key_n, temp); //allocate memory for right son of the previous node
  177.             new_node = temp->right; //new node is the right son of the previous node
  178.         }
  179.         else if (key_n < temp->key) { //if key of new node smaller than previous node key
  180.             temp->left = new Node(data_n, key_n, temp); //allocate memory for left son of the previous node
  181.             new_node = temp->left; //new node is the left son of the previous node
  182.         }
  183.         else //if the key of the new node is equal to the key of the previous node
  184.             temp->data = data_n; //change the data to the data of the added node
  185.         if (temp->color != 0) //if the color of new node is red
  186.             balancingAfterInsert(new_node, temp, temp->parent); //call balancing vertices for new node, his father and his grandfather
  187.     }
  188. }
  189.  
  190. template<class T, typename T1>
  191. void Tree<T, T1>::clear(Node* ptr) //delete map
  192. {
  193.     if (ptr != nullptr) {
  194.         Node* leftptr = ptr->left;
  195.         Node* rightptr = ptr->right;
  196.         delete ptr; //delete parent
  197.         clear(leftptr); //delete left child
  198.         clear(rightptr); //delete right child
  199.     }
  200. }
  201.  
  202. template<class T, typename T1>
  203. void Tree<T, T1>::get_keys(Node* ptr) //returns a list of keys
  204. {
  205.     if (ptr != nullptr) { //if the node exists
  206.         Node* leftptr = ptr->left; //transition to the left branch of a tree
  207.         Node* rightptr = ptr->right; //transition to the right branch of a tree
  208.         cout << " " << ptr->key << " "; //key output for node
  209.         get_keys(ptr->left); //recursive call for the left branch
  210.         get_keys(ptr->right); //recursive call for the right branch
  211.     }
  212. }
  213.  
  214. template<class T, typename T1>
  215. void Tree<T, T1>::get_values(Node* ptr) //returns a list of data
  216. {
  217.     if (ptr != nullptr) { //if the node exists
  218.         Node* leftptr = ptr->left; //transition to the left branch of a tree
  219.         Node* rightptr = ptr->right; //transition to the right branch of a tree
  220.         cout << " " << ptr->data << " "; //data output for node
  221.         get_values(ptr->left); //recursive call for the left branch
  222.         get_values(ptr->right); //recursive call for the right branch
  223.     }
  224. }
  225.  
  226. template<class T, typename T1>
  227. void Tree<T, T1>::GoToMaxLeft(Node* node) //looking for the maximum node from the left subtree (for remove)
  228. {
  229.     Node* temp = node->left; //transition to the left branch of a tree
  230.     while (temp->right != nullptr) { //go to the right branch until you reach the leaf
  231.         temp = temp->right; //transition to the right branch of a tree
  232.     }
  233.     node->data = temp->data; //rewriting the data to the max node from the left subtree
  234.     node->key = temp->key; //rewriting the key to the max node from the left subtree
  235.     if (temp->color == 1) //if max left node color is red
  236.         DeleteRed(temp); //go to method to remove red node
  237.     else
  238.         DeleteBlack(temp); //go to method to remove black node
  239. }
  240.  
  241. template<class T, typename T1>
  242. void Tree<T, T1>::DeleteRed(Node* temp) //delete red node
  243. {
  244.     if (isRightChild(temp)) //division into cases for left and right nodes
  245.     {
  246.         if (temp->right == nullptr && temp->left == nullptr) { //both sons of node are leaves
  247.             temp->parent->right = nullptr; //sever father and son
  248.             delete temp; //delete node
  249.         }
  250.         else if (temp->right != nullptr && temp->left != nullptr) //the node has two sons
  251.             GoToMaxLeft(temp); //select the max node from the left subtree for replacement
  252.         else
  253.         {
  254.             if (temp->right == nullptr) { //the case when the node has one left son
  255.                 temp->parent->right = temp->left; //make grandson son
  256.                 temp->left->parent = temp->parent; //make new father for son of the temp
  257.                 delete temp; //delete node
  258.             }
  259.             else {                                 //the node has one right son
  260.                 temp->parent->right = temp->right; //make grandson son
  261.                 temp->right->parent = temp->parent; //make new father for son of the temp
  262.                 delete temp; //delete node
  263.             }
  264.         }
  265.     }
  266.     else {                                                     //temp is left son
  267.         if (temp->right == nullptr && temp->left == nullptr) { //both sons of node are leaves
  268.             temp->parent->left = nullptr; //sever father and son
  269.             delete temp; //delete node
  270.         }
  271.         else if (temp->right != nullptr && temp->left != nullptr) //the node has two sons
  272.             GoToMaxLeft(temp); //select the max node from the left subtree for replacement
  273.         else
  274.         {
  275.             if (temp->right == nullptr) { //the case when the node has one left son
  276.                 temp->parent->left = temp->left; //make grandson son
  277.                 temp->left->parent = temp->parent; //make new father for son of the temp
  278.                 delete temp; //delete node
  279.             }
  280.             else {                                //the node has one right son
  281.                 temp->parent->left = temp->right; //make grandson son
  282.                 temp->right->parent = temp->parent; //make new father for son of the temp
  283.                 delete temp; //delete node
  284.             }
  285.         }
  286.     }
  287. }
  288.  
  289. template<class T, typename T1>
  290. void Tree<T, T1>::DeleteBlack(Node* temp) //delete black node
  291. {
  292.     if (temp->right == nullptr && temp->left == nullptr) //both sons of node are leaves
  293.     {
  294.         if (temp == root) { //if temp if root
  295.             delete root; //detele node
  296.             root = nullptr; //make root nullptr
  297.         }
  298.         else {
  299.             balancingAfterDelete(temp, temp->parent, isRightChild(temp) ? temp->parent->left : temp->parent->right); //call balancingAfterDelete for the node, his father and his brother
  300.             isRightChild(temp) ? temp->parent->right = nullptr : temp->parent->left = nullptr; //node right/left break his relationship with his father
  301.             delete temp; //delete node
  302.         }
  303.     }
  304.     else if (temp->right == nullptr) // the case when the node has one left son
  305.     {
  306.         if (temp->left->color == 1) //if left son color is red then
  307.         {
  308.             if (temp == root) { //is temp a root?
  309.                 root = temp->left; //make a root left son of the node
  310.                 root->color = 0; //make a root color black
  311.                 root->parent = nullptr; //make a father of root nullptr
  312.                 delete temp; //delete node
  313.             }
  314.             else //if temp is not root then
  315.             {
  316.                 if (isRightChild(temp)) { //if node is the right son
  317.                     temp->left->parent = temp->parent; //make grandson son
  318.                     temp->parent->right = temp->left; //break the bond of father and son
  319.                     temp->left->color = 0; //make his son color black
  320.                     delete temp; //delete node
  321.                 }
  322.                 else {                                 //if node is the left son
  323.                     temp->left->parent = temp->parent; //make grandson son
  324.                     temp->parent->left = temp->left; //break the bond of father and son
  325.                     temp->left->color = 0; //make his son color black
  326.                     delete temp; //delete node
  327.                 }
  328.             }
  329.         }
  330.         else //if the left son color is black
  331.         {
  332.             if (isRightChild(temp)) { //if node is the right son
  333.                 temp->parent->right = temp->left; //break the bond of father and son
  334.                 temp->left->parent = temp->parent; //make grandson son
  335.                 balancingAfterDelete(temp->left, temp->parent, temp->parent->right); //call balancingAfterDelete for the temp left son, temp father and temp brother
  336.             }
  337.             else {                               //if node is the left son
  338.                 temp->parent->left = temp->left; //break the bond of father and son
  339.                 temp->left->parent = temp->parent; //make grandson son
  340.                 balancingAfterDelete(temp->left, temp->parent, temp->parent->right); //call balancingAfterDelete for the temp left son, temp father and temp brother
  341.             }
  342.             delete temp; //delete node
  343.         }
  344.     }
  345.     else if (temp->left == nullptr) //if temp has one right son
  346.     {
  347.         if (temp->right->color == 1) //if left son color is red
  348.         {
  349.             if (temp == root) { //is temp a root?
  350.                 root = temp->right; //make a root right son of the node
  351.                 root->color = 0; //make a root color black
  352.                 root->parent = nullptr; //make a father of root nullptr
  353.                 delete temp; //delete node
  354.             }
  355.             else //if temp son color is black
  356.             {
  357.                 if (isRightChild(temp)) { //if node is the right son
  358.                     temp->right->parent = temp->parent; //make grandson son
  359.                     temp->parent->right = temp->right; //break the bond of father and son
  360.                     temp->right->color = 0; //make his son color black
  361.                     delete temp; //delete node
  362.                 }
  363.                 else {
  364.                     temp->right->parent = temp->parent; //make grandson son
  365.                     temp->parent->left = temp->right; //break the bond of father and son
  366.                     temp->right->color = 0; //make his son color black
  367.                     delete temp; //delete node
  368.                 }
  369.             }
  370.         }
  371.         else //if the node son color black
  372.         {
  373.             if (isRightChild(temp)) { //if the node is the right son
  374.                 temp->parent->right = temp->right; //break the bond of father and son
  375.                 temp->right->parent = temp->parent; //make grandson son
  376.                 balancingAfterDelete(temp->right, temp->parent, temp->parent->left); //call balancingAfterDelete for temp right son, temp father and temp brother
  377.             }
  378.             else { //if the node is the left son
  379.                 temp->parent->left = temp->right; //break the bond of father and son
  380.                 temp->right->parent = temp->parent; //make grandson son
  381.                 balancingAfterDelete(temp->right, temp->parent, temp->parent->left); //call balancingAfterDelete for temp right son, temp father and temp brother
  382.             }
  383.             delete temp; //delete node
  384.             temp = nullptr; //temp pointer nullptr
  385.         }
  386.     }
  387.     else //node has two sons
  388.         GoToMaxLeft(temp); //select the max node from the left subtree for replacement
  389. }
  390.  
  391. template<class T, typename T1>
  392. void Tree<T, T1>::balancingAfterDelete(Node* node, Node* nodePar, Node* brother) //recursive method for fix up changes after node removing
  393. {
  394.     //division into several cases depending on the color of the node father and node brother sons
  395.     if (nodePar->color == 0 && (brother->left == nullptr || brother->left->color == 0) && (brother->right == nullptr || brother->right->color == 0))
  396.     {
  397.         brother->color =1; //recolor brother in red
  398.         if (nodePar != root) //if node parent  isn't a root, call balancingAfterDelete for node father, node grandfather and node brother
  399.             balancingAfterDelete(nodePar, nodePar->parent, isRightChild(nodePar) ? nodePar->parent->left : nodePar->parent->right);
  400.     }
  401.     else if (nodePar->color == 1 && (brother->left == nullptr || brother->left->color == 0) && (brother->right == nullptr || brother->right->color == 0))
  402.     {
  403.         nodePar->color = 0; //recolor father in black
  404.         brother->color =1; //recolor brother in red
  405.     }
  406.     else if (!isRightChild(node) && brother->right != nullptr && brother->right->color == 1)
  407.     {
  408.         brother->right->color = 0; //recolor brother right son in black
  409.         brother->color = nodePar->color; //recolor brother in father color
  410.         nodePar->color = 0; //recolor father in black
  411.         RotateLeft(nodePar); //call left rotation for father
  412.     }
  413.     else if (isRightChild(node) && brother->left != nullptr && brother->left->color == 1)
  414.     {
  415.         brother->left->color = 0; //recolor brother left son in black
  416.         brother->color = nodePar->color; //recolor brother in father color
  417.         nodePar->color = 0; //recolor father in black
  418.         RotateRight(nodePar); //call right rotation for father
  419.     }
  420.     else if (!isRightChild(node) && brother->left != nullptr && brother->left->color == 1)
  421.     {
  422.         brother->left->color = nodePar->color; //recolor brother left son in father color
  423.         nodePar->color = 0; //recolor father in black
  424.         RotateRight(brother); //call right rotation for brother
  425.         RotateLeft(nodePar); //call left rotation for father
  426.     }
  427.     else if (isRightChild(node) && brother->right != nullptr && brother->right->color == 1)
  428.     {
  429.         brother->right->color = nodePar->color; //recolor brother right son in father color
  430.         nodePar->color = 0; //recolor father in black
  431.         RotateLeft(brother); //call left rotation for brother
  432.         RotateRight(nodePar); //call right rotation for father
  433.     }
  434. }
  435.  
  436. template <class T, typename T1>
  437. void Tree<T, T1>::remove(T1 key_n) //remove node by the key
  438. {
  439.         Node* temp = find(key_n); //find the node that want to delete
  440.         if (temp != nullptr) {
  441.             if (temp->color == 1) //if the temp color is red then
  442.                 DeleteRed(temp); //call deleting for red node
  443.             else
  444.                 DeleteBlack(temp); //call deleting for black node
  445.         }
  446. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement