Advertisement
Georgiy031

Untitled

May 15th, 2020
121
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 23.95 KB | None | 0 0
  1. // Copyright 2020 by Ulanov Georgiy under Free Public License 1.0.0
  2.  
  3. /**
  4. \file skiplist.h
  5. \brief skiplist.h - библиотека с реализацией структуры данных
  6. "Очередь с пропусками".
  7.  
  8. SkipList - вероятностная структура данных, основанная на нескольких параллельных
  9. отсортированных связных списках с эффективностью, сравнимой
  10. с двоичным деревом (порядка O(log n) среднее время для большинства
  11. операций)
  12. ![схема](image1.png)
  13. */
  14. #pragma once
  15. #ifndef SKIPLIST_H
  16. #define SKIPLIST_H
  17.  
  18. #include <random>
  19. #include <cstddef>
  20. #include <vector>
  21.  
  22. /**
  23. \brief вероятностная структура данных,
  24. которая содержит упорядоченный набор уникальных объектов.
  25.  
  26. \param [in] T - тип, хранимый в структуре
  27. \param [in] Skip_Factor - основание дроби 1/Skip_Factor - вероятности
  28. появления нового уровня у узла в списке
  29.  
  30. skiplist - вероятностная структура данных,
  31. которая содержит упорядоченный набор уникальных объектов типа <b>T</b>.
  32. Операции поиска, удаления и вставки имеют логарифмическую сложность.
  33. В основе списка с пропусками лежит расширение отсортированного связного
  34. списка дополнительными связями, добавленными в случайных путях
  35. с биномиальным распределением, чтобы поиск по списку мог быстро пропускать
  36. части этого списка.
  37.  
  38. ![схема](image1.png)
  39.  
  40. Нижний слой — это обычный упорядоченный связный список. Каждый более
  41. высокий слой представляет собой «выделенную полосу движения» для списков
  42. ниже, где элемент в i-м слое появляется в i+1-м слое с
  43. вероятностью <b>1/Skip_Factor</b>.
  44.  
  45. Без указания значения <b>Skip_Factor</b> равен 2.
  46. При операции поиска, вставки и удаления ожидаемое число шагов в каждом
  47. связном списке от места начала в текущем списке до места перехода на более
  48. низкий уровень равно значению Skip_Factor. общие ожидаемые затраты
  49. на поиск —
  50. \f$log_p n * p\f$, где p - шаблонный параметр Skip_Factor.
  51. Асимптотика O(log(n)), так как p является константным значением.
  52. */
  53. template <typename T, size_t Skip_Factor = 2>
  54. class skiplist {
  55.     //!< Максимальное количество связанных списков
  56.     const size_t Max_Level = 32;
  57.     //!< структрура, реализующая узел в списке.
  58.     struct node;
  59.   public:
  60.     /**
  61.     \brief позволяет однонапрявленно итерироваться
  62.     по контейнеру skiplist.
  63.  
  64.     skiplist<T, Skip_Factor>::Iterator реализует концепцию ForwardIterator.
  65.     */
  66.     class Iterator {
  67.       public:
  68.         friend class skiplist<T, Skip_Factor>;
  69.         //! \brief Умолчательный конструктор.
  70.         //!
  71.         //! Создает итератор, указывающий на конец списка.
  72.         Iterator() = default;
  73.         //! \brief Деструктор итератора;
  74.         //!не удаляет объект, на который ссылается.
  75.         ~Iterator() = default;
  76.         //! \brief Копирующий конструктор.
  77.         Iterator(const Iterator&) = default;
  78.         //! \brief Оператор присваивания.
  79.         Iterator& operator=(const Iterator&) = default;
  80.         //! \brief Оператор приведения к типу bool.
  81.         //!
  82.         //! Возвращает true, если значение итератора не равно nullptr.
  83.         operator bool();
  84.         //! \brief оператор префиксного инкримента.
  85.         //! \retval Iterator& - значение итератора, идущего следующим.
  86.         Iterator& operator++();
  87.         //! \brief оператор постфиксного инкримента.
  88.         //! \retval Iterator - значение итератора, идущего следующим.
  89.         Iterator operator++(int);
  90.         //! \brief оператор разыменования.
  91.         //! \retval T& - объект из списка, на который указывал итератор.
  92.         T& operator*();
  93.         //! \brief оператор сравнения. Сравнивает значение на равенство.
  94.         //! \retval bool - ссылаются ли два итератора на один объект.
  95.         bool operator== (const Iterator&) const;
  96.         //! \brief оператор сравнения. Сравнивает значение на неравенство.
  97.         //! \retval bool - ссылаются ли два итератора на разные объекты.
  98.         bool operator!= (const Iterator&) const;
  99.       private:
  100.         //!< конструктор, принимающий узел списка в качестве параметра.
  101.         explicit Iterator(node* ref);
  102.         //!< указатель на узел в списке, который хранит объект типа T.
  103.         node* current_node { nullptr };
  104.     };
  105.  
  106.   public:
  107.     //! \brief Умолчательный конструктор.
  108.     //!
  109.     //! Создает пустой список.
  110.     skiplist();
  111.     //! \brief Деструктор экземпляра, освобождает память.
  112.     ~skiplist();
  113.     //! \brief Копирующий конструктор.
  114.     //!
  115.     //! Создается новый список с пропусками с идентичным набором
  116.     //! элементов. Внутреннее строение
  117.     //! полностью меняется в связи с рандомизированным принципом построения.
  118.     skiplist(const skiplist&);
  119.     //! \brief Оператор присваивания.
  120.     //!
  121.     //! Осуществляет глубокое копирование.
  122.     skiplist& operator= (const skiplist&);
  123.    
  124.     //! \brief конструктор, принимающий в качестве параметров два итератора.
  125.     //! \param [in] first итератор, указывающий на первый элемент
  126.     //! упорядоченного набора элементов
  127.     //! \param [in] last итератор, указывающий на элемент после последнего в
  128.     //! упорядоченном наборе элементов
  129.     //!
  130.     //! Позволяет создавать список с пропусками от другого контейнера
  131.     //! c упорядоченным набором элементов.
  132.     template<typename InputIt>
  133.     skiplist(InputIt first, InputIt last) {
  134.         head_ = new node();
  135.         std::vector<node*> refs = { head_ };
  136.         for (InputIt it = first; it != last; ++it) {
  137.             T* value = new T(*it);
  138.             node* insertingNode = new node(value);
  139.             refs[0]->next = insertingNode;
  140.             refs[0] = insertingNode;
  141.             size_t cur_lvl = 0;
  142.             while (++cur_lvl < Max_Level && coin_flip()) {
  143.                 node* newNode = new node(value, nullptr, insertingNode);
  144.                 if (cur_lvl >= count_lvls) {
  145.                     head_ = new node(nullptr, newNode, head_);
  146.                     refs.push_back(head_);
  147.                     count_lvls++;
  148.                 }
  149.                 refs[cur_lvl]->next = newNode;
  150.                 refs[cur_lvl] = newNode;
  151.                 insertingNode = newNode;
  152.             }
  153.             ++size_;
  154.         }
  155.     }
  156.     //! \brief Возвращает итератор на первый элемент
  157.     //!
  158.     //! При пустом контейнере возвращает итератор за конец (см. end()).
  159.     //! \param (Нет)
  160.     //! \retval Iterator на первый элемент
  161.     //!
  162.     //! <b>Сложность</b><br> O(logN), где N - количество элементов в контейнере.
  163.     Iterator begin() const;
  164.     //! \brief Возвращает итератор на элемент, следующий за последним
  165.     //! \param (Нет)
  166.     //! \retval Iterator на элемент, следующий за последним
  167.     //!
  168.     //! <b>Сложность</b><br> константная.
  169.     Iterator end() const;
  170.     //! \brief возвращает итератор на первый элемент не меньше,
  171.     //! чем заданное значение
  172.     //! \param value - ключевое значение для сравнения элементов.
  173.     //! \retval Iterator  на первый элемент, который не
  174.     //! меньше, чем value. Если такой элемент не найден, возвращается
  175.     //! итератор за конец списка (см. end()).
  176.     //!
  177.     //! <b>Сложность</b><br> O(logN), где N - количество элементов в контейнере.
  178.     Iterator lower_bound(const T&) const;
  179.     //! \brief возвращает итератор на первый элемент больше,
  180.     //! чем определенное значение
  181.     //! \param value - ключевое значение для сравнения элементов.
  182.     //! \retval Iterator на первый элемент, который
  183.     //! больше, чем value. Если такой элемент не найден, возвращается
  184.     //! итератор за конец списка (см. end()).
  185.     //!
  186.     //! <b>Сложность</b><br> O(logN), где N - количество элементов в контейнере.
  187.     Iterator upper_bound(const T&) const;
  188.  
  189.     //! \brief  Проверяет отсутствие элементов в контейнере
  190.     //! \param (Нет)
  191.     //! \retval bool <b>true</b>, если контейнер пуст, <b>false</b> иначе
  192.     //!
  193.     //! <b>Сложность</b><br> константная.
  194.     bool empty() const;
  195.     //! \brief Возвращает количество элементов в контейнере.
  196.     //! \param (Нет)
  197.     //! \retval std::ptrdiff_t - количество элементов в контейнере.
  198.     //!
  199.     //! <b>Сложность</b><br> константная.
  200.     std::ptrdiff_t size() const;
  201.     //! \brief Очищает контейнер
  202.     //!
  203.     //! Делает недействительными все ссылки, указатели или итераторы
  204.     //! указывающие на удалённые элементы.
  205.     //! <br><br><b>Сложность</b><br> линейная от размера контейнера.
  206.     void clear();
  207.     //! \brief находит элемент с заданным ключом
  208.     //! \param value - ключевое значение элемента для поиска.
  209.     //! \retval Iterator на элемент со значением value. Если такой элемент
  210.     //! не найден, возвращается итератор, указывающий за конец списка
  211.     //! (см. end()).
  212.     //!
  213.     //! <b>Сложность</b><br> O(logN), где N - количество элементов
  214.     //! в контейнере.
  215.     Iterator find(const T&) const;
  216.     //! \brief Вставляет элемент
  217.     //!
  218.     //! Если элемент с таким значением уже существует, вставка не происходит.
  219.     //! \param value - вставляемое значение
  220.     //! \retval Iterator на вставленный элемент
  221.     //!
  222.     //! <b>Сложность</b><br> O(logN), где N - количество элементов в контейнере
  223.     Iterator insert(const T&);
  224.     //! \brief Удаляет элемент
  225.     //!
  226.     //! Если элемент с таким значением отсутствует в контейнере,
  227.     //! удаление не происходит.
  228.     //! \param value - удаляемое значение
  229.     //! \retval Iterator на следующий элемент после удаляемого.
  230.     //!
  231.     //! <b>Сложность</b><br> O(logN), где N - количество элементов в контейнере
  232.     Iterator erase(const T&);
  233.     //! \brief Удаляет элемент
  234.     //!
  235.     //! Если элемент, на который указывает итератор, отсутствует в контейнере,
  236.     //! удаление не происходит.
  237.     //! \param it - итератор на элемент для удаления
  238.     //! \retval Iterator на следующий элемент после удаляемого.
  239.     //!
  240.     //! <b>Сложность</b><br> O(logN), где N - количество элементов в контейнере
  241.     Iterator erase(Iterator);
  242.     //! \brief находит количество элементов по ключу
  243.     //! \param value - значение ключа
  244.     //! \retval количество элементов с ключом value
  245.     //!
  246.     //! <b>Сложность</b><br> O(logN), где N - количество элементов в контейнере
  247.     std::ptrdiff_t count(const T&) const;
  248.  
  249.   private:
  250.     std::random_device rd;
  251.     //!< возвращает true с вероятностью 1/Skip_Factor
  252.     inline bool coin_flip() { return (rd() % Skip_Factor == 0); }
  253.  
  254.     struct node {
  255.         node() = default;
  256.         explicit node(T* ref_value, node* next_node = nullptr,
  257.              node* down_node = nullptr)
  258.             : value(ref_value)
  259.             , next(next_node)
  260.             , down(down_node) {
  261.         }
  262.  
  263.         T* value {nullptr};
  264.         node* next {nullptr};
  265.         node* down {nullptr};
  266.     };
  267.     size_t count_lvls { 1 };//!< количество параллельных списков.
  268.     node* head_ { nullptr };//!< указатель на начало верхнего списка.
  269.     std::ptrdiff_t size_ { 0 };//!< количество элементов в массиве.
  270. };
  271.  
  272. template <typename T, size_t p>
  273. skiplist<T, p>::Iterator::Iterator(node* ref)
  274.     : current_node(ref) {
  275. }
  276.  
  277. template<typename T, size_t p>
  278. skiplist<T, p>::Iterator::operator bool() {
  279.     return current_node != nullptr;
  280. }
  281.  
  282.  
  283. template<typename T, size_t p>
  284. typename skiplist<T, p>::Iterator& skiplist<T, p>::Iterator::operator++ () {
  285.     current_node = current_node->next;
  286.     return *this;
  287. }
  288.  
  289. template<typename T, size_t p>
  290. typename skiplist<T, p>::Iterator skiplist<T, p>::Iterator::operator++(int) {
  291.     Iterator oldValue = *this;
  292.     current_node = current_node->next;
  293.     return oldValue;
  294. }
  295.  
  296. template<typename T, size_t p>
  297. T& skiplist<T, p>::Iterator::operator*() {
  298.     return *(current_node->value);
  299. }
  300.  
  301. template<typename T, size_t p>
  302. bool skiplist<T, p>::Iterator::operator==
  303.     (const skiplist<T, p>::Iterator& other) const {
  304.     return current_node == other.current_node;
  305. }
  306.  
  307. template<typename T, size_t p>
  308. bool skiplist<T, p>::Iterator::operator!=
  309.     (const skiplist<T, p>::Iterator& other) const {
  310.     return !(*this == other);
  311. }
  312.  
  313. template<typename T, size_t p>
  314. skiplist<T, p>::skiplist() {
  315.     head_ = new node();
  316. }
  317.  
  318. template<typename T, size_t p>
  319. skiplist<T, p>::~skiplist() {
  320.     clear();
  321.     node* curNode = head_;
  322.     while (curNode != nullptr) {
  323.         node* nextNode = curNode->down;
  324.         delete curNode;
  325.         curNode = nextNode;
  326.     }
  327. }
  328.  
  329. template<typename T, size_t p>
  330. skiplist<T, p>::skiplist(const skiplist<T, p>& other) {
  331.     head_ = new node();
  332.     std::vector<node*> refs = { head_ };
  333.     for (Iterator it = other.begin(); it != other.end(); ++it) {
  334.         T* value = new T(*it);
  335.         node* insertingNode = new node(value);
  336.         refs[0]->next = insertingNode;
  337.         refs[0] = insertingNode;
  338.         size_t cur_lvl = 0;
  339.         while (++cur_lvl < Max_Level && coin_flip()) {
  340.             node* newNode = new node(value, nullptr, insertingNode);
  341.             if (cur_lvl >= count_lvls) {
  342.                 head_ = new node(nullptr, newNode, head_);
  343.                 refs.push_back(head_);
  344.                 count_lvls++;
  345.             }
  346.             refs[cur_lvl]->next = newNode;
  347.             refs[cur_lvl] = newNode;
  348.             insertingNode = newNode;
  349.         }
  350.         ++size_;
  351.     }
  352. }
  353.  
  354. template<typename T, size_t p>
  355. skiplist<T, p>& skiplist<T, p>::operator= (const skiplist<T, p>& other) {
  356.     if (this != &other) {
  357.         clear();
  358.         node* curNode = head_;
  359.         while (curNode != nullptr) {
  360.             node* nextNode = curNode->down;
  361.             delete curNode;
  362.             curNode = nextNode;
  363.         }
  364.         size_ = 0;
  365.         count_lvls = 1;
  366.         head_ = new node();
  367.         std::vector<node*> refs = { head_ };
  368.         for (Iterator it = other.begin(); it != other.end(); ++it) {
  369.             T* value = new T(*it);
  370.             node* insertingNode = new node(value);
  371.             refs[0]->next = insertingNode;
  372.             refs[0] = insertingNode;
  373.             size_t cur_lvl = 0;
  374.             while (++cur_lvl < Max_Level && coin_flip()) {
  375.                 node* newNode = new node(value, nullptr, insertingNode);
  376.                 if (cur_lvl >= count_lvls) {
  377.                     head_ = new node(nullptr, newNode, head_);
  378.                     refs.push_back(head_);
  379.                     count_lvls++;
  380.                 }
  381.                 refs[cur_lvl]->next = newNode;
  382.                 refs[cur_lvl] = newNode;
  383.                 insertingNode = newNode;
  384.             }
  385.             ++size_;
  386.         }
  387.     }
  388.     return *this;
  389. }
  390.  
  391. template<typename T, size_t p>
  392. typename skiplist<T, p>::Iterator skiplist<T, p>::begin() const {
  393.     node* curNode = head_;
  394.     while (curNode->down) curNode = curNode->down;
  395.     return skiplist<T, p>::Iterator(curNode->next);
  396. }
  397.  
  398. template<typename T, size_t p>
  399. typename skiplist<T, p>::Iterator skiplist<T, p>::end() const {
  400.     return Iterator(nullptr);
  401. }
  402.  
  403. template<typename T, size_t p>
  404. typename skiplist<T, p>::Iterator
  405.            skiplist<T, p>::lower_bound(const T& value) const {
  406.     node* curNode = head_;
  407.     while (curNode->down != nullptr) {
  408.         if (curNode->next == nullptr || !(*(curNode->next->value) < value)) {
  409.             curNode = curNode->down;
  410.         } else {
  411.             curNode = curNode->next;
  412.         }
  413.     }
  414.     while (curNode->next != nullptr && *(curNode->next->value) < value) {
  415.         curNode = curNode->next;
  416.     }
  417.     return Iterator(curNode->next);
  418. }
  419.  
  420. template<typename T, size_t p>
  421. typename skiplist<T, p>::Iterator
  422.         skiplist<T, p>::upper_bound(const T& value) const {
  423.     node* curNode = head_;
  424.     while (curNode->down != nullptr) {
  425.         if (curNode->next == nullptr || value < *(curNode->next->value)) {
  426.             curNode = curNode->down;
  427.         } else {
  428.             curNode = curNode->next;
  429.         }
  430.     }
  431.     while (curNode->next != nullptr && !(value < *(curNode->next->value))) {
  432.         curNode = curNode->next;
  433.     }
  434.     return Iterator(curNode->next);
  435. }
  436.  
  437. template<typename T, size_t p>
  438. bool skiplist<T, p>::empty() const {
  439.     return size_ == 0;
  440. }
  441.  
  442. template<typename T, size_t p>
  443. std::ptrdiff_t skiplist<T, p>::size() const {
  444.     return size_;
  445. }
  446.  
  447. template<typename T, size_t p>
  448. void skiplist<T, p>::clear() {
  449.     node* curNode = head_;
  450.     node* onDelete;
  451.     node* nextNode;
  452.     while (curNode->down != nullptr) {
  453.         onDelete = curNode->next;
  454.         while (onDelete != nullptr) {
  455.             nextNode = onDelete->next;
  456.             delete onDelete;
  457.             onDelete = nextNode;
  458.         }
  459.         curNode->next = nullptr;
  460.         curNode = curNode->down;
  461.     }
  462.     onDelete = curNode->next;
  463.     curNode->next = nullptr;
  464.     while (onDelete != nullptr) {
  465.         nextNode = onDelete->next;
  466.         delete onDelete->value;
  467.         delete onDelete;
  468.         onDelete = nextNode;
  469.     }
  470.     size_ = 0;
  471. }
  472.  
  473. template<typename T, size_t p>
  474. typename skiplist<T, p>::Iterator skiplist<T, p>::find(const T& value) const {
  475.     node* curNode = head_;
  476.     while (curNode->down != nullptr) {
  477.         if (curNode->next == nullptr || value < *(curNode->next->value)) {
  478.             curNode = curNode->down;
  479.         } else {
  480.             curNode = curNode->next;
  481.         }
  482.     }
  483.     while (curNode->next != nullptr && !(value < *(curNode->next->value))) {
  484.         curNode = curNode->next;
  485.     }
  486.     if (curNode->value == nullptr || *(curNode->value) != value) {
  487.         return end();
  488.     }
  489.     return Iterator(curNode);
  490. }
  491.  
  492. template<typename T, size_t p>
  493. typename skiplist<T, p>::Iterator
  494.         skiplist<T, p>::insert(const T& insertingValue) {
  495.     std::vector<node*> refs(count_lvls);
  496.  
  497.     node* curNode = head_;
  498.     size_t cur_lvl = count_lvls - 1;
  499.  
  500.     while (cur_lvl > 0) {
  501.         if (curNode->next == nullptr ||
  502.                 insertingValue < *(curNode->next->value)) {
  503.             refs[cur_lvl] = curNode;
  504.             --cur_lvl;
  505.             curNode = curNode->down;
  506.         } else {
  507.             curNode = curNode->next;
  508.         }
  509.     }
  510.     while (curNode->next != nullptr &&
  511.             !(insertingValue < *(curNode->next->value))) {
  512.         curNode = curNode->next;
  513.     }
  514.     refs[cur_lvl] = curNode;
  515.  
  516.     if (curNode->value != nullptr && *(curNode->value) == insertingValue) {
  517.         return Iterator(curNode);
  518.     }
  519.     T* data = new T(insertingValue);
  520.     node* insertingNode = new node(data, curNode->next, nullptr);
  521.     curNode->next = insertingNode;
  522.     ++size_;
  523.  
  524.     node* lastInsertingNode = insertingNode;
  525.     while (coin_flip() && ++cur_lvl < Max_Level) {
  526.         node* nextLevelNode = new node(data);
  527.         nextLevelNode->down = lastInsertingNode;
  528.         lastInsertingNode = nextLevelNode;
  529.  
  530.         if (cur_lvl < count_lvls) {
  531.             nextLevelNode->next = refs[cur_lvl]->next;
  532.             refs[cur_lvl]->next = nextLevelNode;
  533.         } else {
  534.             head_ = new node(nullptr, nextLevelNode, head_);
  535.             refs.push_back(head_);
  536.             ++count_lvls;
  537.         }
  538.     }
  539.  
  540.     return Iterator(insertingNode);
  541. }
  542. template<typename T, size_t p>
  543. typename skiplist<T, p>::Iterator skiplist<T, p>::erase(const T& value) {
  544.     std::vector<node*> refs(count_lvls);
  545.     node* curNode = head_;
  546.     size_t cur_lvl = count_lvls - 1;
  547.     while (curNode->down != nullptr) {
  548.         if (curNode->next == nullptr || !(*(curNode->next->value) < value)) {
  549.             refs[cur_lvl] = curNode;
  550.             --cur_lvl;
  551.             curNode = curNode->down;
  552.         } else {
  553.             curNode = curNode->next;
  554.         }
  555.     }
  556.     while (curNode->next != nullptr && *(curNode->next->value) < value) {
  557.         curNode = curNode->next;
  558.     }
  559.     if (curNode->next == nullptr || *(curNode->next->value) != value) {
  560.         return Iterator(curNode->next);
  561.     }
  562.     refs[cur_lvl] = curNode;
  563.     T* ref_on_value = curNode->next->value;
  564.     for (node* ref : refs) {
  565.         if (ref->next == nullptr || ref->next->value != ref_on_value) {
  566.             break;
  567.         }
  568.         node* onDelete = ref->next;;
  569.         ref->next = ref->next->next;
  570.         delete onDelete;
  571.     }
  572.     delete ref_on_value;
  573.     --size_;
  574.     while (head_->next == nullptr && count_lvls > 1) {
  575.         node* next_head = head_->down;
  576.         delete head_;
  577.         head_ = next_head;
  578.         --count_lvls;
  579.     }
  580.     return Iterator((*refs.begin())->next);
  581. }
  582.  
  583. template<typename T, size_t p>
  584. typename skiplist<T, p>::Iterator
  585.         skiplist<T, p>::erase(skiplist<T, p>::Iterator it) {
  586.     return erase(*it);
  587. }
  588.  
  589. template<typename T, size_t p>
  590. std::ptrdiff_t skiplist<T, p>::count(const T& value) const {
  591.     return (find(value) == end() ? 0 : 1);
  592. }
  593. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement