BST.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. #include "BST.h"
  2. #include <cassert>
  3. #include <iostream>
  4. #include <string>
  5. #include <queue>
  6. #include "json.hpp"
  7. BSTNode::BSTNode(int key) :
  8. key_(key),
  9. parent_(std::weak_ptr<BSTNode>()),
  10. left_(nullptr),
  11. right_(nullptr) {}
  12. BSTNode::BSTNode(int key, std::weak_ptr<BSTNode> parent) :
  13. key_(key),
  14. parent_(parent),
  15. left_(nullptr),
  16. right_(nullptr) {}
  17. bool BSTNode::IsLeaf() const {
  18. return left_ == nullptr && right_ == nullptr;
  19. }
  20. bool BSTNode::HasLeftChild() const {
  21. return left_ != nullptr;
  22. }
  23. bool BSTNode::HasRightChild() const {
  24. return right_ != nullptr;
  25. }
  26. void BSTNode::DeleteChild(std::shared_ptr<BSTNode> v) {
  27. if (left_ == v) {
  28. left_ = nullptr;
  29. } else if (right_ == v) {
  30. right_ = nullptr;
  31. } else {
  32. std::cerr << "BSTNode::DeleteChild Error: non-child passed as argument\n";
  33. exit(EXIT_FAILURE);
  34. }
  35. }
  36. void BSTNode::ReplaceChild(std::shared_ptr<BSTNode> v, std::shared_ptr<BSTNode> u) {
  37. if (left_ == u || right_ == u) {
  38. std::cerr << "BSTNode::ReplaceChild Error: child passed as replacement\n";
  39. }
  40. if (left_ == v) {
  41. left_ = u;
  42. u->parent_ = v->parent_;
  43. } else if (right_ == v) {
  44. right_ = u;
  45. u->parent_ = v->parent_;
  46. } else {
  47. std::cerr << "BSTNode::ReplaceChild Error: non-child passed as argument\n";
  48. exit(EXIT_FAILURE);
  49. }
  50. }
  51. BST::BST() : root_(nullptr), size_(0) {}
  52. void BST::Insert(int key) {
  53. if (root_ == nullptr) {
  54. root_ = std::make_shared<BSTNode>(key);
  55. size_++;
  56. return;
  57. }
  58. std::shared_ptr<BSTNode> currentNode = root_, lastNode = nullptr;
  59. while (currentNode != nullptr) {
  60. lastNode = currentNode;
  61. currentNode = (key < currentNode->key_) ?
  62. currentNode->left_ : currentNode->right_;
  63. }
  64. if (key < lastNode->key_) {
  65. lastNode->left_ = std::make_shared<BSTNode>(key, lastNode);
  66. } else {
  67. lastNode->right_ = std::make_shared<BSTNode>(key, lastNode);
  68. }
  69. size_++;
  70. }
  71. bool BST::Delete(int key) {
  72. std::shared_ptr<BSTNode> currentNode = root_;
  73. while (currentNode != nullptr) {
  74. if (currentNode->key_ == key) {
  75. if (currentNode->IsLeaf()) {
  76. DeleteLeaf(currentNode);
  77. } else if (currentNode->left_ == nullptr) {
  78. assert(currentNode->right_ != nullptr);
  79. std::shared_ptr<BSTNode> parent = currentNode->parent_.lock();
  80. parent->ReplaceChild(currentNode, currentNode->right_);
  81. size_--; assert(size_ >= 0);
  82. } else if (currentNode->right_ == nullptr) {
  83. assert(currentNode->left_ != nullptr);
  84. std::shared_ptr<BSTNode> parent = currentNode->parent_.lock();
  85. parent->ReplaceChild(currentNode, currentNode->left_);
  86. size_--; assert(size_ >= 0);
  87. } else {
  88. currentNode->key_ = DeleteMin(currentNode);
  89. }
  90. }
  91. currentNode = (key < currentNode->key_) ?
  92. currentNode->left_ : currentNode->right_;
  93. }
  94. return false;
  95. }
  96. int BST::DeleteMin() {
  97. return DeleteMin(root_);
  98. }
  99. void BST::DeleteLeaf(std::shared_ptr<BSTNode> currentNode) {
  100. std::shared_ptr<BSTNode> parent = currentNode->parent_.lock();
  101. if (parent == nullptr) {
  102. // Delete root
  103. root_ = nullptr;
  104. size_--; assert(size_ == 0);
  105. } else {
  106. if (parent->right_ == currentNode) {
  107. parent->right_ = nullptr;
  108. } else if (parent->left_ == currentNode) {
  109. parent->left_ = nullptr;
  110. } else {
  111. std::cerr << "BST::DeleteLeaf Error: inconsistent state\n";
  112. }
  113. size_--; assert(size_ >= 0);
  114. }
  115. }
  116. int BST::DeleteMin(std::shared_ptr<BSTNode> currentNode) {
  117. std::shared_ptr<BSTNode> lastNode = nullptr;
  118. while (currentNode != nullptr) {
  119. lastNode = currentNode;
  120. currentNode = currentNode->left_;
  121. }
  122. int result = lastNode->key_;
  123. std::shared_ptr<BSTNode> parent = lastNode->parent_.lock();
  124. if (parent == nullptr) {
  125. // lastNode is root
  126. if (lastNode->right_ != nullptr) {
  127. root_ = lastNode->right_;
  128. lastNode->right_->parent_.reset();
  129. } else {
  130. root_ = nullptr;
  131. }
  132. } else {
  133. // lastNode under the root
  134. if (lastNode->right_ != nullptr) {
  135. parent->left_ = lastNode->right_;
  136. lastNode->right_->parent_ = parent;
  137. } else {
  138. parent->left_ = nullptr;
  139. }
  140. }
  141. size_--; assert(size_ >= 0);
  142. return result;
  143. }
  144. size_t BST::size() const {
  145. return size_;
  146. }
  147. bool BST::empty() const {
  148. return size_ == 0;
  149. }
  150. bool BST::Find(int key) const {
  151. std::shared_ptr<BSTNode> currentNode = root_;
  152. while (currentNode != nullptr) {
  153. if (currentNode->key_ == key) {
  154. return true;
  155. }
  156. currentNode = (key < currentNode->key_) ?
  157. currentNode->left_ : currentNode->right_;
  158. }
  159. return false;
  160. }
  161. std::string BST::JSON() const {
  162. nlohmann::json result;
  163. std::queue< std::shared_ptr<BSTNode> > nodes;
  164. if (root_ != nullptr) {
  165. result["root"] = root_->key_;
  166. nodes.push(root_);
  167. while (!nodes.empty()) {
  168. auto v = nodes.front();
  169. nodes.pop();
  170. std::string key = std::to_string(v->key_);
  171. if (v->left_ != nullptr) {
  172. result[key]["left"] = v->left_->key_;
  173. nodes.push(v->left_);
  174. }
  175. if (v->right_ != nullptr) {
  176. result[key]["right"] = v->right_->key_;
  177. nodes.push(v->right_);
  178. }
  179. if (v->parent_.lock() != nullptr) {
  180. result[key]["parent"] = v->parent_.lock()->key_;
  181. } else {
  182. result[key]["root"] = true;
  183. }
  184. }
  185. }
  186. result["size"] = size_;
  187. return result.dump(2) + "\n";
  188. }