Advertisement
Sailein

Tree lib

May 23rd, 2018
144
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.42 KB | None | 0 0
  1. //
  2. // Created by Sailein on 27.05.2018.
  3. //
  4.  
  5. #ifndef IAMGROOT_GROOTTREE_H
  6. #define IAMGROOT_GROOTTREE_H
  7.  
  8. #include <iostream>
  9. #include <string>
  10. #include <sstream>
  11. #include <cmath>
  12.  
  13. using namespace std;
  14.  
  15. struct Complex //стуктура комплексных чисел
  16. {
  17.     double re, im;
  18.     Complex (double re = 0.0, double im = 0.0) : re(re), im(im) {} // constructor
  19.     Complex (const Complex& other)
  20.     {
  21.         *this = other;
  22.     }
  23.     Complex operator+(const Complex& other) const // & - ссылка - чтобы не копировать
  24.     {
  25.         return Complex(re + other.re, im + other.im);
  26.     }
  27.     Complex operator*(const Complex& other) const
  28.     {
  29.         return Complex((re * other.re - im * other.im), (re * other.im + other.re * im));
  30.     }
  31.     Complex operator*(double scalar) const
  32.     {
  33.         return Complex(re * scalar, im * scalar);
  34.     }
  35.     const Complex& operator=(const Complex& other)
  36.     {
  37.         this->re = other.re;
  38.         this->im = other.im;
  39.         return *this;
  40.     }
  41.     double modulus () const
  42.     {
  43.         return sqrt(pow(re, 2.0) + pow(im, 2.0));
  44.     }
  45.     bool operator!= (const Complex& other) const
  46.     {
  47.         return (this->re != other.re) && (this->im != other.im);
  48.     }
  49.     bool operator== (const Complex& other) const
  50.     {
  51.         return (this->re == other.re) && (this->im == other.im);
  52.     }
  53.     bool operator<(double num) const
  54.     {
  55.         return modulus() < num;
  56.     }
  57.     bool operator>(double num) const
  58.     {
  59.         return modulus() > num;
  60.     }
  61. };
  62.  
  63. ostream& operator<<(ostream& os, const Complex& number)
  64. {
  65.     return os << number.re << " + " << number.im << "i ";
  66. }
  67.  
  68. istream& operator>>(istream& is, Complex& number)
  69. {
  70.     return is >> number.re >> number.im;
  71. }
  72.  
  73. template <typename T>
  74. class Tree; // объявление класса Дерево
  75.  
  76. template <typename T>
  77. struct Operation // дефолтная операция для обхода (ничего не делаем) - все что наследуется используем в траверсе
  78. {
  79.     virtual void operator()(const T& element) {}
  80. };
  81.  
  82. template <typename T>
  83. struct CloneOperation: public Operation<T> // операция клонирования деревьев
  84. {
  85.     Tree<T>& result;
  86.     CloneOperation(Tree<T>& reciever) : result(reciever) {}
  87.     virtual void operator()(const T& element)
  88.     {
  89.         result.insert(element);
  90.     }
  91. };
  92.  
  93. template <typename T>
  94. struct StringPrintOperation: public Operation<T> // операция вывода элементов в строку
  95. {
  96.     string result;
  97.     virtual void operator()(const T& element)
  98.     {
  99.         result += to_string(element) + ",";
  100.     }
  101. };
  102.  
  103. template <typename T, typename F>
  104. struct MapOperation: public Operation<T> // операция мап - применение функции
  105. {
  106.     Tree<F> result;
  107.     F (*func) (const T& element);
  108.     MapOperation( F (*func) (const T& element)) : func(func) {}
  109.     virtual void operator()(const T& element)
  110.     {
  111.         result.insert(func(element));
  112.     }
  113. };
  114.  
  115. template <typename T>
  116. struct WhereOperation: public Operation<T> // операция мап - применение функции
  117. {
  118.     Tree<T> result;
  119.     bool (*func) (const T& element);
  120.     WhereOperation( bool (*func) (const T& element)) : func(func) {}
  121.     virtual void operator()(const T& element)
  122.     {
  123.         result.insert(func(element));
  124.     }
  125. };
  126.  
  127. template <typename T>
  128. class Tree // Я ЕСТЬ ГРУТ
  129. {
  130. private:
  131.     class Node // элемент древа - право лево назад  и данные
  132.     {
  133.     private:
  134.         T m_data;
  135.         Node* m_left;
  136.         Node* m_right;
  137.         Node* m_parent;
  138.     public:
  139.         Node (const T& data, Node* parent = nullptr, Node* left = nullptr, Node* right = nullptr) // конструктор
  140.                 : m_data(data), m_parent(parent), m_left(left), m_right(right) {};
  141.         const T& data() const // все сеттеры и геттеры
  142.         {
  143.             return m_data;
  144.         }
  145.         void setData(const T& data)
  146.         {
  147.             m_data = data;
  148.         }
  149.         Node* parent()  const
  150.         {
  151.             return m_parent;
  152.         }
  153.         Node* left() const
  154.         {
  155.             return m_left;
  156.         }
  157.         Node* right() const
  158.         {
  159.             return m_right;
  160.         }
  161.         void setLeft(Node* left)
  162.         {
  163.             m_left = left;
  164.         }
  165.         void setRight(Node* right)
  166.         {
  167.             m_right = right;
  168.         }
  169.         void setParent(Node* parent)
  170.         {
  171.             m_parent = parent;
  172.         }
  173.     };
  174.     Node* m_root = nullptr;
  175.     size_t m_size = 0;
  176. public:
  177.     Tree<T>() {} // конструктор по умолчанию
  178.     Tree<T>(string row)
  179.     {
  180.         insertFromString(row); // конструктор древа из строки
  181.     }
  182.     Tree<T>(const char* row)
  183.     {
  184.         insertFromString(row); // конструктор древа из строки еще 1
  185.     }
  186.     Tree<T> (const Tree<T>& other) // конструктор копирования
  187.     {
  188.         *this = other;
  189.     }
  190.     void insert (const T& element) // ввод элемента - самое важное
  191.     {
  192.         if (root() == nullptr)
  193.         {
  194.             setRoot(new Node(element));
  195.             return;
  196.         }
  197.         Node* cur = root(); // cur - current временная переменная
  198.         while (element != cur->data())
  199.         {
  200.             if (element > cur->data())
  201.             {
  202.                 if (cur->right() == nullptr)
  203.                 {
  204.                     cur->setRight(new Node(element, cur));
  205.                     return;
  206.                 }
  207.                 cur = cur->right();
  208.             }
  209.             else if (element < cur->data())
  210.             {
  211.                 if (cur->left() == nullptr)
  212.                 {
  213.                     cur->setLeft(new Node(element, cur));
  214.                     return;
  215.                 }
  216.                 cur = cur->left();
  217.             }
  218.         }
  219.     }
  220.     void traverse (Operation<T>& operation, string type = "kpl") const // обход - публик версия - регистронезависим
  221.     {
  222.         traverse(root(), operation, type);
  223.     }
  224.     bool containsElement (const T& element) const // есть ли вхождение элемента? (!)
  225.     {
  226.         return search(element) != nullptr;
  227.     }
  228.     Tree<T> extract (const T& element) const // извлечение поддерева по элементу (!)
  229.     {
  230.         Tree<T> result;
  231.         CloneOperation<T> clone(result);
  232.         Node* subRoot = search(element);
  233.         traverse(subRoot, clone); //обход с копированием
  234.         return clone.result;
  235.     }
  236.     string toString (string traverseType) const // извлечение в строку (!)
  237.     {
  238.         StringPrintOperation<T> row;
  239.         traverse(root(), row, traverseType);
  240.         return row.result.substr(0, row.result.size()-1); //убираем последнюю запятую. и если элеменетов нет то пишем пустую строку
  241.     }
  242.     void insertFromString (string row) // чтениче из строки и построение дерева (!)
  243.     {
  244.         for (size_t i = 0; i < row.size();) //проверить < or <= наш цикл идет от запятой до запятой
  245.         {
  246.             size_t j = row.find(',', i + 1);
  247.             T tmp;
  248.             istringstream stream (row.substr(i, j));
  249.             stream >> tmp;
  250.             insert(tmp);
  251.             if (j == string::npos)  return;
  252.             i = j + 1;
  253.         }
  254.     }
  255.     const Tree<T>& operator=(const Tree<T>& other)
  256.     {
  257.         CloneOperation<T> clone(*this);
  258.         other.traverse(clone); //обход с копированием
  259.         return *this;
  260.     }
  261.     friend Tree<T> operator+(const Tree<T>& tree1, const Tree<T>& tree2) //слияние (!)
  262.     {
  263.         Tree<T> result;
  264.         CloneOperation<T> clone(result);
  265.         tree1.traverse(clone);
  266.         tree2.traverse(clone);
  267.         return clone.result;
  268.     }
  269.     template <typename F>
  270.     Tree<F> map (F (*func) (const T& element)) const // map (!) - используем лямбда функции
  271.     {
  272.         MapOperation<T, F> mapOp(func);
  273.         traverse(mapOp);
  274.         return mapOp.result;
  275.     }
  276.     Tree<T> where (bool (*func) (const T& element)) const // where (!)
  277.     {
  278.         WhereOperation<T> whereOp(func);
  279.         traverse(whereOp);
  280.         return whereOp.result;
  281.     }
  282. protected:// так как они используют Node* - а это внутренне устройство дерева, мы его защитим
  283.     Node* root() const
  284.     {
  285.         return m_root;
  286.     }
  287.     void setRoot (Node* root)
  288.     {
  289.         m_root = root;
  290.     }
  291.     // Обходы: * КЛП * КПЛ * ЛПК * ЛКП * ПЛК * ПКЛ; К – корень Л – лево (левое поддерево) П – право (правое поддерево)
  292.     void traverse (Node* node, Operation<T>& operation, string type = "kpl") const //обход
  293.     {
  294.         if (node == nullptr) return;
  295.         for (int i = 0; i < 3; ++i)
  296.         {
  297.             if ((type[i] == 'K') || (type[i] == 'k'))
  298.             {
  299.                 operation(node->data()); // "K"
  300.             }
  301.             else if ((type[i] == 'P') || (type[i] == 'p'))
  302.             {
  303.                 traverse(node->right(), operation, type); // "P"
  304.             }
  305.             else if ((type[i] == 'L') || (type[i] == 'l'))
  306.             {
  307.                 traverse(node->left(), operation, type); // "L"
  308.             }
  309.         }
  310.     }
  311.     Node* search (const T& element) const // поиск элемента - это как insert , но ток без изменений
  312.     {
  313.         if (root() == nullptr) return nullptr;
  314.         Node* cur = root();
  315.         while (element != cur->data())
  316.         {
  317.             if (element > cur->data())
  318.             {
  319.                 if (cur->right() == nullptr)
  320.                 {
  321.                     return nullptr;
  322.                 }
  323.                 cur = cur->right();
  324.             }
  325.             else if (element < cur->data())
  326.             {
  327.                 if (cur->left() == nullptr)
  328.                 {
  329.                     return nullptr;
  330.                 }
  331.                 cur = cur->left();
  332.             }
  333.         }
  334.         return cur;
  335.     }
  336. };
  337. #endif //IAMGROOT_GROOTTREE_H
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement