Advertisement
Ilya_Bykonya

Untitled

Oct 8th, 2022
623
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.42 KB | None | 0 0
  1. #include <functional>
  2. #include <iostream>
  3. #include <random>
  4.  
  5. class BinaryTreeNode {
  6. private:
  7.     const int64_t m_value;
  8.     std::unique_ptr<BinaryTreeNode> m_left = {};
  9.     std::unique_ptr<BinaryTreeNode> m_right = {};
  10. public:
  11.     BinaryTreeNode(int64_t value) : m_value{ value } {}
  12.  
  13.     int64_t value() const { return m_value; }
  14.     const BinaryTreeNode* left() const { return m_left.get(); }
  15.     const BinaryTreeNode* right() const { return m_right.get(); }
  16.     std::unique_ptr<BinaryTreeNode> takeLeft() { return std::move(m_left); }
  17.     std::unique_ptr<BinaryTreeNode> takeRight() { return std::move(m_right); }
  18. public:
  19.     void insert(int64_t value) {
  20.         if (value < m_value) {
  21.             if (m_left) {
  22.                 m_left->insert(value);
  23.             } else {
  24.                 m_left = std::make_unique<BinaryTreeNode>(value);
  25.             }
  26.         } else if(value > m_value) {
  27.             if (m_right) {
  28.                 m_right->insert(value);
  29.             } else {
  30.                 m_right = std::make_unique<BinaryTreeNode>(value);
  31.             }
  32.         }
  33.     }
  34. };
  35. class AbstractTreeCrawler {
  36. public:
  37.     virtual ~AbstractTreeCrawler() noexcept = default;
  38.     void travel(const BinaryTreeNode* node) {
  39.         recursiveUseNode(node, 0);
  40.     }
  41. private:
  42.     virtual void recursiveUseNode(const BinaryTreeNode* node, size_t offset) const = 0;
  43. };
  44. class BinarySearchTree {
  45. private:
  46.     std::unique_ptr<BinaryTreeNode> m_head = {};
  47.     size_t m_size = {};
  48. public:
  49.     void insert(int64_t value) {
  50.         if (m_head) {
  51.             m_head->insert(value);
  52.         } else {
  53.             m_head = std::make_unique<BinaryTreeNode>(value);
  54.         }
  55.     }
  56.  
  57.     void travelBy(std::unique_ptr<AbstractTreeCrawler> crawler) {
  58.         crawler->travel(m_head.get());
  59.     }
  60. };
  61.  
  62.  
  63. struct BackwardTraversal : public AbstractTreeCrawler {
  64. private:
  65.     std::function<void(int64_t, size_t)> m_operation;
  66. public:
  67.     BackwardTraversal(std::function<void(int64_t, size_t)> operation): m_operation { std::move(operation) }{}
  68. private:
  69.     virtual void recursiveUseNode(const BinaryTreeNode* node, size_t offset) const override {
  70.         if (node == nullptr)
  71.             return;
  72.  
  73.         recursiveUseNode(node->left(), offset + 1);
  74.         recursiveUseNode(node->right(), offset + 1);
  75.         m_operation(node->value(), offset);
  76.     }
  77. };
  78. struct SymmetricTraversal : public AbstractTreeCrawler {
  79. private:
  80.     std::function<void(int64_t, size_t)> m_operation;
  81. public:
  82.     SymmetricTraversal(std::function<void(int64_t, size_t)> operation) : m_operation{ std::move(operation) } {}
  83. private:
  84.     virtual void recursiveUseNode(const BinaryTreeNode* node, size_t offset) const override {
  85.         if (node == nullptr)
  86.             return;
  87.  
  88.         recursiveUseNode(node->left(), offset + 1);
  89.         m_operation(node->value(), offset);
  90.         recursiveUseNode(node->right(), offset + 1);
  91.     }
  92. };
  93. struct ForwardTraversal : public AbstractTreeCrawler {
  94. private:
  95.     std::function<void(int64_t, size_t)> m_operation;
  96. public:
  97.     ForwardTraversal(std::function<void(int64_t, size_t)> operation) : m_operation{ std::move(operation) } {}
  98. private:
  99.     virtual void recursiveUseNode(const BinaryTreeNode* node, size_t offset) const override {
  100.         if (node == nullptr)
  101.             return;
  102.  
  103.         m_operation(node->value(), offset);
  104.         recursiveUseNode(node->left(), offset + 1);
  105.         recursiveUseNode(node->right(), offset + 1);
  106.     }
  107. };
  108.  
  109.  
  110. int main() {
  111.     BinarySearchTree tree_1;
  112.     BinarySearchTree tree_2;
  113.     auto generator = std::bind(std::uniform_int_distribution<int64_t>{ 0, 100 }, std::mt19937{ std::random_device{}() });
  114.  
  115.     for (int i = 0; i < 10; ++i)
  116.         tree_1.insert(generator());
  117.     for (int i = 0; i < 10; ++i)
  118.         tree_2.insert(generator());
  119.  
  120.  
  121.     std::cout << "====================================================" << std::endl;
  122.     tree_1.travelBy(std::make_unique<BackwardTraversal>([](int64_t value, size_t offset) {
  123.         std::cout << std::string(offset, '\t') << value << std::endl;
  124.         }));
  125.     std::cout << "====================================================" << std::endl;
  126.     tree_1.travelBy(std::make_unique<SymmetricTraversal>([](int64_t value, size_t offset) {
  127.             std::cout << std::string(offset, '\t') << value << std::endl;
  128.         }));
  129.  
  130.     std::cout << "====================================================" << std::endl;
  131.     tree_2.travelBy(std::make_unique<ForwardTraversal>([&tree_1](int64_t value, size_t) {
  132.             tree_1.insert(value);
  133.         }));
  134.     std::cout << "====================================================" << std::endl;
  135.     tree_1.travelBy(std::make_unique<SymmetricTraversal>([](int64_t value, size_t offset) {
  136.         std::cout << std::string(offset, '\t') << value << std::endl;
  137.         }));
  138.     std::cout << "====================================================" << std::endl;
  139. }
  140.  
  141.  
  142.  
  143.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement