Advertisement
Argent007

Binary Search Tree 2024

Dec 21st, 2024
20
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.38 KB | None | 0 0
  1. // ConsoleApplication1.cpp : Этот файл содержит функцию "main". Здесь начинается и заканчивается выполнение программы.
  2. //
  3.  
  4. #include <iostream>
  5. #include <optional>
  6. #include <stack>
  7. #include <string>
  8. #include <functional>
  9. #include <queue>
  10.  
  11. template <typename Key, typename Data>
  12. class bst
  13. {
  14.     struct node
  15.     {
  16.         Key key;
  17.         Data data;
  18.         node* left = nullptr, * right = nullptr;
  19.     } *root = nullptr;
  20.     size_t count = 0;
  21.     //возвращает адрес указателя, по которому должен располагаться узел с ключом k
  22.     node** _find(const Key& k)const;
  23. public:
  24.     bst() {};
  25.     ~bst();
  26.     std::optional<std::reference_wrapper<Data>> find(const Key& k)const;
  27.     void insert(const Key& k, const Data& d);
  28.     std::optional<Key> findnext(const Key& k)const;
  29.     std::optional<Key> findprev(const Key& k)const;
  30.     void remove(const Key& k);
  31.     void visit(std::function<void(const Key&, const Data&)> worker) const;
  32.     size_t height() const; //вычисление высоты с помощью очереди
  33.     size_t height2() const; //вычисление высоты с помощью стека
  34.     std::vector<std::pair<Key, Data>> dump() const;
  35.     bool is_bst_by_secondary_key() const;
  36.     int width() const;
  37. };
  38.  
  39.  
  40.  
  41. int main()
  42. {
  43.     bst<std::string, int> t;
  44.     t.insert("one", 1);
  45.     t.insert("two", 2);
  46.     t.insert("three", 3);
  47.     t.insert("four", 4);
  48.     t.insert("five", 5);
  49.     t.insert("six", 6);
  50.     t.insert("seven", 7);
  51.     t.insert("eight", 8);
  52.     t.insert("nine", 9);
  53.     t.insert("ten", 10);
  54.     t.insert("eleven", 11);
  55.     t.insert("twelve", 12);
  56.     std::cout << t.width() << std::endl;
  57.     std::cout << t.height() << " " << t.height2() << std::endl;
  58.     auto dump = t.dump();
  59.     for (auto [k, d] : dump)
  60.         std::cout << k << " " << d << std::endl;
  61.  
  62.     std::cout << *t.find("five") << std::endl;
  63.     (*t.find("five")).get() = 50;
  64.     (int&)*t.find("five") = 500;
  65.     std::cout << *t.find("five") << std::endl;
  66.  
  67.     std::cout << "Hello World!\n";
  68. }
  69.  
  70. // Запуск программы: CTRL+F5 или меню "Отладка" > "Запуск без отладки"
  71. // Отладка программы: F5 или меню "Отладка" > "Запустить отладку"
  72.  
  73. // Советы по началу работы
  74. //   1. В окне обозревателя решений можно добавлять файлы и управлять ими.
  75. //   2. В окне Team Explorer можно подключиться к системе управления версиями.
  76. //   3. В окне "Выходные данные" можно просматривать выходные данные сборки и другие сообщения.
  77. //   4. В окне "Список ошибок" можно просматривать ошибки.
  78. //   5. Последовательно выберите пункты меню "Проект" > "Добавить новый элемент", чтобы создать файлы кода, или "Проект" > "Добавить существующий элемент", чтобы добавить в проект существующие файлы кода.
  79. //   6. Чтобы снова открыть этот проект позже, выберите пункты меню "Файл" > "Открыть" > "Проект" и выберите SLN-файл.
  80.  
  81. template<typename Key, typename Data>
  82. typename bst<Key, Data>::node** bst<Key, Data>::_find(const Key& k) const
  83. {
  84.     node** p = (node**)&root;
  85.     while (*p && (*p)->key != k)
  86.         p = (*p)->key < k ? &((*p)->right) : &((*p)->left);
  87.     return p;
  88. }
  89.  
  90. template<typename Key, typename Data>
  91. bst<Key, Data>::~bst()
  92. {
  93.     std::stack<node*> s;
  94.     node* current = root;
  95.     while (current || s.size())
  96.     {
  97.         if (current)
  98.         {
  99.             s.push(current);
  100.             current = current->left;
  101.         }
  102.         else
  103.         {
  104.             current = s.top()->right;
  105.             delete s.top();
  106.             s.pop();
  107.         }
  108.     }
  109. }
  110.  
  111. template<typename Key, typename Data>
  112. std::optional<std::reference_wrapper<Data>> bst<Key, Data>::find(const Key& k) const
  113. {
  114.     auto p = _find(k);
  115.     if (*p) return (*p)->data;
  116.     return std::nullopt;
  117. }
  118.  
  119. template<typename Key, typename Data>
  120. void bst<Key, Data>::insert(const Key& k, const Data& d)
  121. {
  122.     auto p = _find(k);
  123.     if (*p) (*p)->data = d;
  124.     else
  125.     {
  126.         *p = new node{ k,d };
  127.         ++count;
  128.     }
  129. }
  130.  
  131. template<typename Key, typename Data>
  132. std::optional<Key> bst<Key, Data>::findnext(const Key& k) const
  133. {
  134.     node** p = (node**)&root;
  135.     node** lastleft = nullptr;
  136.     while (*p)
  137.         p = k < (*p)->key ? (lastleft = p, &((*p)->left)) : &((*p)->right);
  138.     return lastleft ? std::optional<Key>((*lastleft)->key) : std::nullopt;
  139. }
  140.  
  141. template<typename Key, typename Data>
  142. void bst<Key, Data>::remove(const Key& k)
  143. {
  144.     node** p = _find(k);
  145.     if (*p == nullptr) return;
  146.     --count;
  147.     if (!(*p)->left || !(*p)->right)
  148.     {
  149.         auto tmp = *p;
  150.         *p = tmp->left ? tmp->left : tmp->right;
  151.         delete tmp;
  152.     }
  153.     else {
  154.         auto nxt = &(*p)->right;
  155.         while ((*nxt)->left) nxt = &(*nxt)->left;
  156.         (*p)->key = (*nxt)->key;
  157.         (*p)->data = (*nxt)->data;
  158.         node* tmp = *nxt;
  159.         *nxt = tmp->right;
  160.         delete tmp;
  161.     }
  162. }
  163.  
  164. template<typename Key, typename Data>
  165. void bst<Key, Data>::visit(std::function<void(const Key&, const Data&)> worker) const
  166. {
  167.     std::stack<node*> s;
  168.     node* current = root;
  169.     while (current || s.size())
  170.     {
  171.         if (current)
  172.         {
  173.             s.push(current);
  174.             current = current->left;
  175.         }
  176.         else
  177.         {
  178.             current = s.top()->right;
  179.             worker(s.top()->key, s.top()->data);
  180.             s.pop();
  181.         }
  182.     }
  183. }
  184.  
  185. template<typename Key, typename Data>
  186. size_t bst<Key, Data>::height() const
  187. {
  188.     if (!root) return 0;
  189.     std::queue<node*> Q;
  190.     size_t h = 0;
  191.     Q.push(root);
  192.     while (Q.size())
  193.     {
  194.         ++h;
  195.         size_t level_size = Q.size();
  196.         for (size_t i = 0; i < level_size; i++)
  197.         {
  198.             auto p = Q.front();
  199.             Q.pop();
  200.             if (p->left) Q.push(p->left);
  201.             if (p->right) Q.push(p->right);
  202.         }
  203.     }
  204.     return h;
  205. }
  206.  
  207. template<typename Key, typename Data>
  208. size_t bst<Key, Data>::height2() const
  209. {
  210.     std::stack<std::pair<node*, size_t>> s;
  211.     node* current = root;
  212.     size_t current_level = 0, maxlevel = 0;
  213.     while (current || s.size())
  214.     {
  215.         if (current)
  216.         {
  217.             s.push({ current,current_level });
  218.             current = current->left;
  219.             ++current_level;
  220.         }
  221.         else
  222.         {
  223.             maxlevel = std::max(maxlevel, s.top().second);
  224.             current = s.top().first->right;
  225.             current_level = s.top().second + 1;
  226.             s.pop();
  227.         }
  228.     }
  229.     return maxlevel;
  230. }
  231.  
  232. template<typename Key, typename Data>
  233. std::vector<std::pair<Key, Data>> bst<Key, Data>::dump() const
  234. {
  235.     std::vector<std::pair<Key, Data>> dmpvec;
  236.     this->visit([&dmpvec](const Key& k, const Data& d) {dmpvec.push_back({ k,d }); return; });
  237.     return dmpvec;
  238. }
  239.  
  240. template<typename Key, typename Data>
  241. bool bst<Key, Data>::is_bst_by_secondary_key() const
  242. {
  243.     std::optional<Data> prevdata;
  244.     bool result = true;
  245.     visit([&result, &prevdata](const Key& k, const Data& d) {
  246.         if (prevdata && !(*prevdata < d))
  247.             result = false;
  248.         prevdata = d;
  249.         });
  250.     return result;
  251. }
  252.  
  253. template<typename Key, typename Data>
  254. int bst<Key, Data>::width() const
  255. {
  256.     std::stack<std::pair<node*, int>> s;
  257.     node* current = root;
  258.     int current_shift = 0;
  259.     int minshift = 0, maxshift = 0;
  260.     while (current || s.size())
  261.     {
  262.         if (current)
  263.         {
  264.             s.push({ current,current_shift });
  265.             current = current->left;
  266.             current_shift--;
  267.         }
  268.         else
  269.         {
  270.             minshift = std::min(minshift, s.top().second);
  271.             maxshift = std::max(maxshift, s.top().second);
  272.             current = s.top().first->right;
  273.             current_shift = s.top().second + 1;
  274.             s.pop();
  275.         }
  276.     }
  277.     return maxshift - minshift;
  278. }
  279.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement