Advertisement
Guest User

Tree.h

a guest
Mar 29th, 2020
115
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.76 KB | None | 0 0
  1. #ifndef __BINARY_SEARCH_TREE_H
  2. #define __BINARY_SEARCH_TREE_H
  3.  
  4. #include <iostream>
  5. #include <functional>
  6. using namespace std;
  7. //
  8. // Определение шаблона класса BinarySearchTree
  9. //
  10.  
  11. template <class T>
  12. class BinarySearchTree
  13. {
  14. public:
  15.  
  16.     // Конструктор "по умолчанию" создает пустое дерево
  17.     BinarySearchTree() : root_(nullptr) {}
  18.  
  19.     // Деструктор освобождает память, занятую узлами дерева
  20.     virtual ~BinarySearchTree()
  21.     {
  22.         deleteSubtree(root_);
  23.     }
  24.  
  25.     // Печать строкового изображения дерева в выходной поток out
  26.     void print(ostream& out) const
  27.     {
  28.         printNode(out, root_);
  29.         out << endl;
  30.     }
  31.  
  32.     // Функция поиска по ключу в бинарном дереве поиска
  33.     bool iterativeSearch(const T& key) const
  34.     {
  35.         return (iterativeSearchNode(key) != nullptr);
  36.     }
  37.  
  38.     // Вставка нового элемента в дерево, не нарушающая порядка
  39.     // элементов. Вставка производится в лист дерева
  40.     void insert(const T& key)
  41.     {
  42.         return iterativeInsert(key);
  43.  
  44.     }
  45.     //вставка нового элемента (рекурсивно)
  46.     void recInsert(const T& key)
  47.     {
  48.         return recursiveInsert(key);
  49.  
  50.     }
  51.     // Удаление элемента из дерева, не нарушающее порядка элементов
  52.     void deleteKey(const T& key)
  53.     {
  54.         return remove(key);
  55.     }
  56.  
  57.     // Определение количества узлов дерева
  58.     int getCount() const
  59.     {
  60.         return getCountSubTree(this->root_);
  61.     }
  62.  
  63.     // Определение высоты дерева
  64.     int getHeight() const
  65.     {
  66.         return getHeightSubTree(this->root_);
  67.     }
  68.     //Поиск элемента следующего за указанным
  69.     void searchN(const T& key) const
  70.     {
  71.         return searchNext(key);
  72.     }
  73.     //Вывод информации узла с заданным номером
  74.     void getInfo()
  75.     {
  76.  
  77.     }
  78.     //Удаление без изменения
  79.     void del(const T& key)
  80.     {
  81.         return remove(key);
  82.     }
  83.  
  84. private:
  85.  
  86.     // Функция поиска адреса узла по ключу в бинарном дереве поиска
  87.     Node* iterativeSearchNode(const T& key) const
  88.     {
  89.         Node* current = root_;
  90.         while (current != nullptr)
  91.         {
  92.             while (key != current->key_)
  93.             {
  94.                 current = (current->key_ < key ? current->right_ : current->left_);
  95.             }
  96.  
  97.         }
  98.         return current;
  99.     }
  100.  
  101.     //
  102.     // Рекурсивные функции, представляющие
  103.     // рекурсивные тела основных интерфейсных методов
  104.     //
  105.     // Рекурсивная функция для освобождения памяти
  106.     void deleteSubtree(Node* node)
  107.     {
  108.         if (node != nullptr)
  109.         {
  110.             deleteSubtree(node->left_);
  111.             deleteSubtree(node->right_);
  112.             delete node;
  113.         }
  114.     }
  115.  
  116.     // Рекурсивная функция определения количества узлов дерева
  117.     int getCountSubTree(Node* node) const
  118.     {
  119.         if (node == nullptr)
  120.             return 0;
  121.         return (1 + getCountSubTree(node->left_) +
  122.             getCountSubTree(node->right_));
  123.     }
  124.  
  125.     // Рекурсивная функция определения высоты дерева
  126.     int getHeightSubTree(Node* node) const
  127.     {
  128.         if (node == nullptr)
  129.         {
  130.             return 0;
  131.         }
  132.         int left = getHeightSubTree(node->left_);
  133.         int right = getHeightSubTree(node->right_);
  134.         return 1 + (left < right ? right : left);
  135.     }
  136.  
  137.     // Рекурсивная функция для вывода изображения дерева в выходной поток
  138.     void printNode(ostream& out, Node* root) const
  139.     {
  140.         // Изображение дерева заключается в круглые скобки.
  141.         out << '(';
  142.         if (root)
  143.         {
  144.             // Для узлов дерева должна быть определена (или переопределена)
  145.             // операция вывода в выходной поток <<
  146.             out << root->key_;
  147.             printNode(out, root->left_);
  148.             printNode(out, root->right_);
  149.         }
  150.         out << ')';
  151.     }
  152.  
  153.     // Рекурсивная функция для организации обхода узлов дерева.
  154.     void inorderWalk(Node* node, const std::funnction<void(const T&)>& func) const
  155.     {
  156.         if (node != nullptr)
  157.         {
  158.             inorderWalk(node->left_);
  159.             func(node->key_);
  160.             inorderWalk(node->right_);
  161.         }
  162.     }
  163.  
  164.     //Добавление нового элемента в дерево (итеративно)
  165.     void iterativeInsert(Node** node, const T& key)
  166.     {
  167.         while (*node != nullptr)
  168.         {
  169.             node = &(key < (*node)->key_ ? (*node)->left_ : (*node)->right_);
  170.         }
  171.         *node = new Node(key);
  172.     }
  173.  
  174.     /*void iterInsert(Node* node, const T& key)
  175.     {
  176.         while (node != nullptr)
  177.         {
  178.             if (node->key_ <= key)
  179.             {
  180.                 if (node->right_ == nullptr)
  181.                 {
  182.                     node->right_ = new Node(key);
  183.                     return;
  184.                 }
  185.                 node = node->right_;
  186.             }
  187.             else
  188.             {
  189.                 if (node->left_ == nullptr)
  190.                 {
  191.                     node->left_ = new Node(key);
  192.                     return;
  193.                 }
  194.                 node = node->left_;
  195.             }
  196.         }
  197.     }*/
  198.  
  199.     //Добавление нового элемента в дерево (рекурсивно)
  200.     void recursiveInsert(Node*& node, const T& key)
  201.     {
  202.         if (node == nullptr)
  203.         {
  204.             node = new Node(key);
  205.         }
  206.         else
  207.         {
  208.             recursiveInsert((key < node->key_ ? node->left_ : node->right_), key);
  209.         }
  210.     }
  211.     //Поиск элемента следующего за указанным
  212.     const Node* searchNext(Node* node, const T& key)
  213.     {
  214.         if (node == nullptr)
  215.         {
  216.             return nullptr;
  217.         }
  218.         if (key >= node->key_)
  219.         {
  220.             return searchNext(node->right_);
  221.         }
  222.         else
  223.         {
  224.             const Node* temp = searchNext(node->left_);
  225.             return (temp == nullptr ? node : temp);
  226.         }
  227.     }
  228.     //Вспомогательная функция
  229.     Node* cutMin(Node* node)
  230.     {
  231.         if (node == nullptr)
  232.         {
  233.             return node;
  234.         } if (node->left_ == nullptr)
  235.         {
  236.             return node->right_;
  237.         }
  238.         node->left_ = cutMin(node->left_);
  239.         return node;
  240.     }
  241.  
  242.     //Вспомогательная функция 2
  243.     Node* getMin(Node* node)
  244.     {
  245.         while (node->left_ != nullptr)
  246.         {
  247.             node = node->left_;
  248.         }
  249.         return node;
  250.     }
  251.     //Удаление элемента из дерева, не нарушающее порядка элементов
  252.     Node* remove(Node* node, const T& key)
  253.     {
  254.         if (node == nullptr)
  255.         {
  256.             return node;
  257.         } if (key < node->key_)
  258.         {
  259.             node->left_ = remove(node->left_, key);
  260.         }
  261.         else if (key > node->key_)
  262.         {
  263.             node->right_ = remove(node->right_, key);
  264.         }
  265.         else
  266.         {
  267.             Node* left = node->left_;
  268.             Node* right = node->right_;
  269.             delete node;
  270.             if (left == nullptr)
  271.             {
  272.                 return remove(right, key);
  273.             }
  274.             else if (right == nullptr)
  275.             {
  276.                 return left;
  277.             }
  278.             Node* temp = getMin(right);
  279.             right = cutMin(right);
  280.             temp->left_ = left;
  281.             temp->right_ = remove(right, key);
  282.             return temp;
  283.         }
  284.         return node;
  285.     }
  286.    
  287.  
  288.     // Описание структуры узла со ссылками на детей
  289.     struct Node
  290.     {
  291.         // Конструктор узла
  292.         Node(const T& key, Node* left = nullptr, Node* right = nullptr,
  293.             Node* p = nullptr) :
  294.             key_(key), left_(left), right_(right), p_(p) {}
  295.         T key_; // значение ключа, содержащееся в узле
  296.         Node* left_; // указатель на левое поддерево
  297.         Node* right_; // указатель на правое поддерево
  298.         Node* p_; // указатель на родителя !!! не используется
  299.     };
  300.  
  301.     // Дерево реализовано в виде указателя на корневой узел.
  302.     Node* root_;
  303. };
  304. // конец шаблона класса TreeBinarySearchTree
  305.  
  306. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement