PGSStas

Untitled

Dec 13th, 2019
828
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 12.81 KB | None | 0 0
  1. #ifndef BINARY_SEARCH_TREE_H_
  2. #define BINARY_SEARCH_TREE_H_
  3. #include <vector>
  4. #include <iostream>
  5. #include "set_interface.h"
  6.  
  7. template<typename T>
  8. class BinarySearchTree : public SetInterface<T> {
  9.  protected:
  10.   struct TreeNode;
  11.  public:
  12.   class ConstIterator : public std::iterator<std::bidirectional_iterator_tag,
  13.                                              T> {
  14.    public:
  15.     const T& operator*() const;
  16.     const T* operator->() const;
  17.  
  18.     ConstIterator& operator++();
  19.     ConstIterator operator++(int);
  20.  
  21.     ConstIterator& operator--();
  22.     ConstIterator operator--(int);
  23.  
  24.     bool operator==(const ConstIterator&) const;
  25.     bool operator!=(const ConstIterator&) const;
  26.  
  27.    private:
  28.     ConstIterator(TreeNode* element, bool is_end);
  29.     TreeNode* element_;
  30.     bool is_end_;
  31.  
  32.     friend class BinarySearchTree;
  33.   };
  34.   BinarySearchTree() : size_(0), top_node_(nullptr), begin_(nullptr) {}
  35.   BinarySearchTree(const std::initializer_list<T>& list);
  36.  
  37.   BinarySearchTree(const BinarySearchTree<T>& other_tree);
  38.   BinarySearchTree& operator=(const BinarySearchTree& other_tree);
  39.  
  40.   BinarySearchTree(BinarySearchTree<T>&& other_tree);
  41.   BinarySearchTree& operator=(BinarySearchTree&& other_tree);
  42.   ~BinarySearchTree();
  43.  
  44.   int size() const override;
  45.   bool empty() const override;
  46.   bool contains(const T& value) const override;
  47.   void insert(const T& value) override;
  48.   void erase(const T& value) override;
  49.   std::vector<T> ToVector() const override;
  50.  
  51.   bool operator==(const BinarySearchTree& other_tree) const;
  52.   bool operator!=(const BinarySearchTree& other_tree) const;
  53.  
  54.   virtual int count(const T& value) const;
  55.  
  56.   ConstIterator begin() const;
  57.   ConstIterator end() const;
  58.  
  59.   void erase(const ConstIterator& value);
  60.  
  61.   ConstIterator find(const T& value) const;
  62.  
  63.  protected:
  64.   TreeNode* GetNode(const T& value) const;
  65.   void ReplaceNode(TreeNode* old_node, TreeNode* new_node);
  66.   TreeNode* GetLowestInSubTree(TreeNode* cur_node) const;
  67.   void CreateVector(TreeNode* current_node, std::vector<T>* result) const;
  68.   void VectorToTree(int l, int r, const std::vector<T>& vector_to_copy);
  69.   void DestroyNode(TreeNode* node);
  70.  
  71.   struct TreeNode {
  72.     T value;
  73.     TreeNode* parent;
  74.     TreeNode* left;
  75.     TreeNode* right;
  76.    private:
  77.     TreeNode(const T&, TreeNode*, TreeNode*, TreeNode*);
  78.     friend class BinarySearchTree;
  79.   };
  80.  
  81.   int size_;
  82.   TreeNode* top_node_;
  83.   TreeNode* begin_;
  84. };
  85.  
  86. template<typename T>
  87. const T& BinarySearchTree<T>::ConstIterator::operator*() const {
  88.   return element_->value;
  89. }
  90.  
  91. template<typename T>
  92. const T* BinarySearchTree<T>::ConstIterator::operator->() const {
  93.   return &(element_->value);
  94. }
  95.  
  96. template<typename T>
  97. bool BinarySearchTree<T>::ConstIterator::operator==(
  98.     const BinarySearchTree::ConstIterator& second_itr) const {
  99.   return element_ == second_itr.element_ && is_end_ == second_itr.is_end_;
  100. }
  101.  
  102. template<typename T>
  103. bool BinarySearchTree<T>::ConstIterator::operator!=(
  104.     const BinarySearchTree::ConstIterator& second_itr) const {
  105.   return !(*this == second_itr);
  106. }
  107.  
  108. template<typename T>
  109. typename BinarySearchTree<T>::ConstIterator&
  110. BinarySearchTree<T>::ConstIterator::operator++() {
  111.   if (element_->right != nullptr) {
  112.     element_ = element_->right;
  113.     while (element_->left != nullptr) {
  114.       element_ = element_->left;
  115.     }
  116.   } else {
  117.     TreeNode* prev = nullptr;
  118.     while (element_->right == prev && element_->parent != nullptr) {
  119.       prev = element_;
  120.       element_ = element_->parent;
  121.     }
  122.     if (element_->right == prev) {
  123.       is_end_ = true;
  124.     }
  125.   }
  126.   return *this;
  127. }
  128.  
  129. template<typename T>
  130. typename BinarySearchTree<T>::ConstIterator
  131. BinarySearchTree<T>::ConstIterator::operator++(int) {
  132.   auto temp = *this;
  133.   ++(*this);
  134.   return temp;
  135. }
  136.  
  137. template<typename T>
  138. typename BinarySearchTree<T>::ConstIterator&
  139. BinarySearchTree<T>::ConstIterator::operator--() {
  140.   if (is_end_) {
  141.     is_end_ = false;
  142.     while (element_->right != nullptr) {
  143.       element_ = element_->right;
  144.     }
  145.   } else {
  146.     if (element_->left != nullptr) {
  147.       element_ = element_->left;
  148.       while (element_->right != nullptr) {
  149.         element_ = element_->right;
  150.       }
  151.     } else {
  152.       TreeNode* prev = nullptr;
  153.       while (element_->left == prev && element_->parent != nullptr) {
  154.         prev = element_;
  155.         element_ = element_->parent;
  156.       }
  157.       assert(element_->left != prev);
  158.     }
  159.   }
  160.   return *this;
  161. }
  162. template<typename T>
  163. typename BinarySearchTree<T>::ConstIterator
  164. BinarySearchTree<T>::ConstIterator::operator--(int) {
  165.   auto temp = *this;
  166.   --(*this);
  167.   return temp;
  168. }
  169.  
  170. template<typename T>
  171. BinarySearchTree<T>::ConstIterator::ConstIterator(
  172.     BinarySearchTree::TreeNode* element, bool is_end):
  173.     element_(element),
  174.     is_end_(is_end) {}
  175.  
  176. template<typename T>
  177. BinarySearchTree<T>::TreeNode::TreeNode(const T& value,
  178.                                         BinarySearchTree::TreeNode* parent,
  179.                                         BinarySearchTree::TreeNode* left,
  180.                                         BinarySearchTree::TreeNode* right)
  181.     : value(value), parent(parent), left(left), right(right) {}
  182.  
  183. template<typename T>
  184. BinarySearchTree<T>::BinarySearchTree(const std::initializer_list<T>& list) {
  185.   size_ = 0;
  186.   for (auto& i : list) {
  187.     insert(i);
  188.   }
  189. }
  190.  
  191. template<typename T>
  192. BinarySearchTree<T>::BinarySearchTree(const BinarySearchTree<T>& other_tree) {
  193.   std::vector<T> vector_to_copy = other_tree.ToVector();
  194.   size_ = 0;
  195.   VectorToTree(0, other_tree.size() - 1, vector_to_copy);
  196. }
  197.  
  198. template<typename T>
  199. BinarySearchTree<T>& BinarySearchTree<T>::operator=(
  200.     const BinarySearchTree& other_tree) {
  201.   if (this == &other_tree) {
  202.     return *this;
  203.   }
  204.   DestroyNode(top_node_);
  205.   top_node_ = begin_ = nullptr;
  206.   std::vector<T> vector_to_copy = other_tree.ToVector();
  207.   VectorToTree(0, other_tree.size() - 1, vector_to_copy);
  208. }
  209.  
  210. template<typename T>
  211. BinarySearchTree<T>::BinarySearchTree(BinarySearchTree<T>&& other_tree) {
  212.   top_node_ = other_tree.top_node_;
  213.   size_ = other_tree.size_;
  214.   begin_ = other_tree.begin_;
  215.   other_tree.top_node_ = other_tree.begin_ = nullptr;
  216.   other_tree.size_ = 0;
  217. }
  218.  
  219. template<typename T>
  220. BinarySearchTree<T>& BinarySearchTree<T>::operator=(
  221.     BinarySearchTree&& other_tree) {
  222.   if (this == &other_tree) {
  223.     return *this;
  224.   }
  225.   DestroyNode(top_node_);
  226.   top_node_ = other_tree.top_node_;
  227.   size_ = other_tree.size_;
  228.   begin_ = other_tree.begin_;
  229.   other_tree.top_node_ = other_tree.begin_ = nullptr;
  230.   other_tree.size_ = 0;
  231. }
  232.  
  233. template<typename T>
  234. int BinarySearchTree<T>::size() const {
  235.   return size_;
  236. }
  237.  
  238. template<typename T>
  239. bool BinarySearchTree<T>::empty() const {
  240.   return size_ == 0;
  241. }
  242.  
  243. template<typename T>
  244. bool BinarySearchTree<T>::contains(const T& value) const {
  245.   TreeNode* current_node = GetNode(value);
  246.   return current_node != nullptr;
  247. }
  248. template<typename T>
  249. void BinarySearchTree<T>::insert(const T& value) {
  250.   size_++;
  251.   if (size_ == 1) {
  252.     top_node_ = new TreeNode(value, nullptr, nullptr, nullptr);
  253.     begin_ = top_node_;
  254.     return;
  255.   }
  256.   TreeNode* current_node = top_node_;
  257.   TreeNode* prev_node = nullptr;
  258.   while (current_node != nullptr) {
  259.     prev_node = current_node;
  260.     if (current_node->value < value) {
  261.       current_node = current_node->right;
  262.     } else {
  263.       current_node = current_node->left;
  264.  
  265.     }
  266.   }
  267.   auto* new_node = new TreeNode(value, prev_node, nullptr, nullptr);
  268.   if (prev_node->value < value) {
  269.     prev_node->right = new_node;
  270.   } else {
  271.     prev_node->left = new_node;
  272.  
  273.   }
  274.   if (begin_->left != nullptr) {
  275.     begin_ = begin_->left;
  276.   }
  277. }
  278.  
  279. template<typename T>
  280. void BinarySearchTree<T>::erase(const T& value) {
  281.   TreeNode* current_node = GetNode(value);
  282.   if (current_node == nullptr) {
  283.     return;
  284.   }
  285.   size_--;
  286.   if (current_node->left == nullptr || current_node->right == nullptr) {
  287.     TreeNode* new_node;
  288.     if (current_node->left != nullptr) {
  289.       new_node = current_node->left;
  290.     } else {
  291.       new_node = current_node->right;
  292.     }
  293.  
  294.     ReplaceNode(current_node, new_node);
  295.   } else {
  296.     TreeNode* new_node = GetLowestInSubTree(current_node->right);
  297.     new_node->left = current_node->left;
  298.     ReplaceNode(new_node, nullptr);
  299.     new_node->right = current_node->right;
  300.     ReplaceNode(current_node, new_node);
  301.   }
  302.   if (current_node == begin_) {
  303.     begin_ = top_node_;
  304.     while (begin_ != nullptr && begin_->left != nullptr) {
  305.       begin_ = begin_->left;
  306.     }
  307.   }
  308.   delete current_node;
  309. }
  310.  
  311. template<typename T>
  312. typename BinarySearchTree<T>::TreeNode*
  313. BinarySearchTree<T>::GetNode(const T& value) const {
  314.   TreeNode* current_node = top_node_;
  315.   TreeNode* ans = nullptr;
  316.   while (current_node != nullptr) {
  317.     if (!(current_node->value < value) && !(value < current_node->value)) {
  318.       ans = current_node;
  319.     }
  320.     if (current_node->value < value) {
  321.       current_node = current_node->right;
  322.     } else {
  323.       current_node = current_node->left;
  324.     }
  325.   }
  326.   return ans;
  327. }
  328. template<typename T>
  329. void BinarySearchTree<T>::ReplaceNode(BinarySearchTree::TreeNode* old_node,
  330.                                       BinarySearchTree::TreeNode* new_node) {
  331.   TreeNode* parent = old_node->parent;
  332.   if (parent != nullptr) {
  333.     if (parent->left == old_node) {
  334.       parent->left = new_node;
  335.     } else {
  336.       parent->right = new_node;
  337.     }
  338.   } else {
  339.     top_node_ = new_node;
  340.   }
  341.   if (new_node != nullptr) {
  342.     new_node->parent = parent;
  343.     if (new_node->left != nullptr) {
  344.       new_node->left->parent = new_node;
  345.     }
  346.     if (new_node->right != nullptr) {
  347.       new_node->right->parent = new_node;
  348.     }
  349.   }
  350. }
  351.  
  352. template<typename T>
  353. typename BinarySearchTree<T>::TreeNode* BinarySearchTree<T>::GetLowestInSubTree(
  354.     BinarySearchTree::TreeNode* cur_node) const {
  355.   while (cur_node != nullptr && cur_node->left != nullptr) {
  356.     cur_node = cur_node->left;
  357.   }
  358.   return cur_node;
  359. }
  360.  
  361. template<typename T>
  362. std::vector<T> BinarySearchTree<T>::ToVector() const {
  363.   std::vector<T> result;
  364.   CreateVector(top_node_, &result);
  365.   return result;
  366. }
  367.  
  368. template<typename T>
  369. void BinarySearchTree<T>::CreateVector(BinarySearchTree<T>::TreeNode* current_node,
  370.                                        std::vector<T>* result) const {
  371.   if (current_node == nullptr) {
  372.     return;
  373.   }
  374.   CreateVector(current_node->left, result);
  375.   result->push_back(current_node->value);
  376.   CreateVector(current_node->right, result);
  377. }
  378.  
  379. template<typename T>
  380. bool BinarySearchTree<T>::operator==(const BinarySearchTree& other_tree) const {
  381.   if (size_ != other_tree.size_) {
  382.     return false;
  383.   }
  384.   std::vector<T> first_vector = ToVector();
  385.   std::vector<T> second_vector = other_tree.ToVector();
  386.   for (int i = 0; i < first_vector.size(); i++) {
  387.     if (first_vector[i] < second_vector[i]
  388.         || second_vector[i] < first_vector[i]) {
  389.       return false;
  390.     }
  391.   }
  392.   return true;
  393. }
  394.  
  395. template<typename T>
  396. bool BinarySearchTree<T>::operator!=(const BinarySearchTree& other_tree) const {
  397.   return !(*this == other_tree);
  398. }
  399.  
  400. template<typename T>
  401. int BinarySearchTree<T>::count(const T& value) const {
  402.   int counter = 0;
  403.   TreeNode* current_node = top_node_;
  404.   while (current_node != nullptr) {
  405.     if (!(current_node->value < value) && !(value < current_node->value)) {
  406.       counter++;
  407.     }
  408.     if (current_node->value < value) {
  409.       current_node = current_node->right;
  410.     } else {
  411.       current_node = current_node->left;
  412.     }
  413.   }
  414.   return counter;
  415. }
  416.  
  417. template<typename T>
  418. void BinarySearchTree<T>::VectorToTree(int l, int r,
  419.                                        const std::vector<T>& vector_to_copy) {
  420.   if (l > r) {
  421.     return;
  422.   }
  423.   int m = (l + r) / 2;
  424.   insert(vector_to_copy[m]);
  425.   VectorToTree(l, m - 1, vector_to_copy);
  426.   VectorToTree(m + 1, r, vector_to_copy);
  427. }
  428.  
  429. template<typename T>
  430. void BinarySearchTree<T>::DestroyNode(TreeNode* node) {
  431.   if (node == nullptr) {
  432.     return;
  433.   }
  434.   DestroyNode(node->left);
  435.   DestroyNode(node->right);
  436.   delete node;
  437.   size_--;
  438. }
  439.  
  440. template<typename T>
  441. BinarySearchTree<T>::~BinarySearchTree() {
  442.   DestroyNode(top_node_);
  443. }
  444.  
  445. template<typename T>
  446. typename BinarySearchTree<T>::ConstIterator BinarySearchTree<T>::begin() const {
  447.   return ConstIterator(begin_, size_ == 0);
  448. }
  449.  
  450. template<typename T>
  451. typename BinarySearchTree<T>::ConstIterator BinarySearchTree<T>::end() const {
  452.   return ConstIterator(top_node_, true);
  453. }
  454.  
  455. template<typename T>
  456. void BinarySearchTree<T>::erase(const BinarySearchTree::ConstIterator& value) {
  457.   erase(value.element_);
  458. }
  459.  
  460. template<typename T>
  461. typename BinarySearchTree<T>::ConstIterator BinarySearchTree<T>::find(
  462.     const T& value) const {
  463.   TreeNode* node = GetNode(value);
  464.   if (node == nullptr) {
  465.     return ConstIterator(top_node_, true);
  466.   }
  467.   return ConstIterator(node, false);
  468. }
  469.  
  470. #endif  // BINARY_SEARCH_TREE_H_
Advertisement
Add Comment
Please, Sign In to add comment