Guest User

Untitled

a guest
Sep 15th, 2023
111
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.52 KB | None | 0 0
  1. #include <iostream>
  2. #include <stdexcept>
  3. #include <utility>
  4. #include <memory>
  5. #include <string>
  6. #define RED true
  7. #define BLACK false
  8.  
  9. class RBTree;
  10. class Node {
  11. friend class RBTree;
  12. friend void left_rotate(RBTree &tree, std::shared_ptr<Node> &subtree_root);
  13. friend void right_rotate(RBTree &tree, std::shared_ptr<Node> &subtree_root);
  14. public:
  15. Node() {}
  16. Node(const std::pair<std::string, std::string> &values, bool color): values(values), color(color) {}
  17.  
  18. std::string get_key() {
  19. return values.first;
  20. }
  21.  
  22. std::string &get_value() {
  23. return values.second;
  24. }
  25.  
  26. private:
  27. std::pair<std::string, std::string> values;
  28. std::shared_ptr<Node> left = nullptr;
  29. std::shared_ptr<Node> right = nullptr;
  30. std::shared_ptr<Node> parent = nullptr;
  31. bool color;
  32. };
  33.  
  34.  
  35. class RBTree {
  36. friend void left_rotate(RBTree &tree, std::shared_ptr<Node> &subtree_root);
  37. friend void right_rotate(RBTree &tree, std::shared_ptr<Node> &subtree_root);
  38. public:
  39. RBTree() {}
  40. std::string &operator[](const std::string &rhs);
  41. void remove(const std::string &key);
  42.  
  43. size_t size() const {
  44. return current_size;
  45. }
  46.  
  47. std::string at(const std::string &key);
  48.  
  49. private:
  50. std::shared_ptr<Node> root_node;
  51. size_t current_size = 0;
  52. static std::shared_ptr<Node> traverse(const std::string &value, std::shared_ptr<Node> &current);
  53. static std::shared_ptr<Node> insert(const std::string &key,
  54. std::shared_ptr<Node> &insertion_point,
  55. RBTree &tree);
  56. };
  57.  
  58.  
  59. void left_rotate(RBTree &tree, std::shared_ptr<Node> &subtree_root) {
  60. std::shared_ptr<Node> new_subtree_root = subtree_root->right;
  61. subtree_root->right = new_subtree_root->left;
  62.  
  63. if (new_subtree_root->left != nullptr)
  64. new_subtree_root->left->parent = subtree_root;
  65.  
  66. new_subtree_root->parent = subtree_root->parent;
  67.  
  68. if (subtree_root->parent == nullptr)
  69. tree.root_node = new_subtree_root;
  70. else if (subtree_root == subtree_root->parent->left)
  71. subtree_root->parent->left = new_subtree_root;
  72. else
  73. subtree_root->parent->right = new_subtree_root;
  74.  
  75. new_subtree_root->left = subtree_root;
  76. subtree_root->parent = new_subtree_root;
  77. }
  78.  
  79.  
  80. void right_rotate(RBTree &tree, std::shared_ptr<Node> &subtree_root) {
  81. std::shared_ptr<Node> new_subtree_root = subtree_root->left;
  82. subtree_root->left = new_subtree_root->right;
  83.  
  84. if (new_subtree_root->right != nullptr)
  85. new_subtree_root->right->parent = new_subtree_root;
  86.  
  87. new_subtree_root->parent = subtree_root->parent;
  88.  
  89. if (subtree_root->parent == nullptr)
  90. tree.root_node = new_subtree_root;
  91. else if (subtree_root == subtree_root->parent->left)
  92. subtree_root->parent->left = new_subtree_root;
  93. else
  94. subtree_root->parent->right = new_subtree_root;
  95.  
  96. new_subtree_root->right = subtree_root;
  97. subtree_root->parent = new_subtree_root;
  98. }
  99.  
  100.  
  101. std::shared_ptr<Node> RBTree::insert(const std::string &key,
  102. std::shared_ptr<Node> &insertion_point,
  103. RBTree &tree) {
  104. Node new_node({key, ""}, RED);
  105.  
  106. if (tree.root_node == nullptr) {
  107. new_node.color = BLACK;
  108. tree.root_node = std::make_shared<Node>(new_node);
  109. return tree.root_node;
  110. } else {
  111. if (key < insertion_point->get_key()) {
  112. insertion_point->left = std::make_shared<Node>(new_node);
  113. insertion_point->left->parent = insertion_point;
  114.  
  115. if (insertion_point->color == RED)
  116. insertion_point->left->color = BLACK;
  117.  
  118. if (insertion_point->left->color == BLACK && insertion_point->right == nullptr)
  119. right_rotate(tree, insertion_point);
  120.  
  121. return insertion_point->left;
  122. } else {
  123. insertion_point->right = std::make_shared<Node>(new_node);
  124. insertion_point->right->parent = insertion_point;
  125.  
  126. if (insertion_point->color == RED)
  127. insertion_point->right->color = BLACK;
  128.  
  129. if (insertion_point->right->color == BLACK && insertion_point->right == nullptr)
  130. left_rotate(tree, insertion_point);
  131.  
  132. return insertion_point->right;
  133. }
  134. }
  135. }
  136.  
  137.  
  138. std::shared_ptr<Node> RBTree::traverse(const std::string &value, std::shared_ptr<Node> &current) {
  139. if (value < current->get_key()) {
  140. if (current->left == nullptr)
  141. return current;
  142.  
  143. return traverse(value, current->left);
  144. }
  145.  
  146. if (value > current->get_key()) {
  147. if (current->right == nullptr)
  148. return current;
  149.  
  150. return traverse(value, current->right);
  151. }
  152.  
  153. return current;
  154. }
  155.  
  156.  
  157. void RBTree::remove(const std::string &key) {
  158. if (root_node == nullptr)
  159. throw std::out_of_range("the tree is empty");
  160.  
  161. std::shared_ptr<Node> to_delete = traverse(key, root_node);
  162. bool to_the_left = false;
  163. bool to_the_right = false;
  164.  
  165. if (to_delete->get_key() != key)
  166. throw std::out_of_range(key + " not found");
  167.  
  168. if (to_delete == to_delete->parent->left) {
  169. to_delete->parent->left = nullptr;
  170. to_the_left = true;
  171. } else {
  172. to_delete->parent->right = nullptr;
  173. to_the_right = true;
  174. }
  175.  
  176. std::shared_ptr<Node> deleted_node_parent = to_delete->parent;
  177. to_delete->parent = nullptr;
  178.  
  179. if (to_the_left) {
  180. if (deleted_node_parent->color == BLACK && deleted_node_parent->right == nullptr)
  181. right_rotate(*this, deleted_node_parent);
  182. } else if (to_the_right) {
  183. if (deleted_node_parent->color == BLACK && deleted_node_parent->left == nullptr)
  184. left_rotate(*this, deleted_node_parent);
  185. }
  186. }
  187.  
  188.  
  189. std::string &RBTree::operator[](const std::string &rhs) {
  190. if (root_node == nullptr)
  191. return insert(rhs, root_node, *this)->get_value();
  192.  
  193. std::shared_ptr<Node> current = traverse(rhs, root_node);
  194.  
  195. if (current->get_key() != rhs)
  196. return insert(rhs, current, *this)->get_value();
  197.  
  198. return current->get_value();
  199. }
  200.  
  201.  
  202. std::string RBTree::at(const std::string &key) {
  203. std::shared_ptr<Node> match = traverse(key, root_node);
  204.  
  205. if (match->get_key() == key)
  206. return match->get_value();
  207.  
  208. throw std::out_of_range(key + " not found");
  209. }
  210.  
  211.  
  212. int main() {
  213. RBTree test;
  214.  
  215. test["red"] = "black";
  216. test["black"] = "red";
  217. test["green"] = "blue";
  218. test["mauve"] = "mauve";
  219. test["abc"] = "def";
  220. test["PanAm"] = "Boeing 747";
  221. test["twitter"] = "x";
  222. test.remove("twitter");
  223.  
  224. try {
  225. std::cout << test.at("twitter") << std::endl;
  226. } catch (std::out_of_range err) {
  227. std::cout << err.what() << std::endl;
  228. }
  229.  
  230. std::cout << test["mauve"] << std::endl;
  231. std::cout << test["PanAm"] << std::endl;
  232.  
  233. return 0;
  234. }
Advertisement
Add Comment
Please, Sign In to add comment