Advertisement
Guest User

arkadye's smart linked list

a guest
Oct 15th, 2014
227
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.28 KB | None | 0 0
  1. // smartlinkedlist.h
  2.  
  3. #include <functional>
  4. #include <mutex>
  5. #include <vector>
  6.  
  7. template<typename Type , typename Compare = std::less<Type>>
  8. class SmartList
  9. {
  10. private:
  11.     class Node
  12.     {
  13.         Type value;
  14.         Node* nextNewest;
  15.         Node* nextBiggest;
  16.     public:
  17.         Node(Type val, Node* newest, Node* bigger) : value(val), nextNewest(newest), nextBiggest(bigger) {}
  18.         Type getValue() const { return value; }
  19.         Node* getNextBiggest() const { return nextBiggest; }
  20.         Node* getNextNewest() const { return nextNewest; }
  21.         void setNextBiggest(Node* nb) { nextBiggest = nb; }
  22.         void setNextNewest(Node* nn) { nextNewest = nn; }
  23.     };
  24.  
  25.     Compare cmpFn;
  26.     Node* smallest;
  27.     Node* newest;
  28.     mutable std::mutex lock;
  29.  
  30.     Node* getLargestSmallerThan(const Type& val)
  31.     {
  32.         if (smallest == nullptr || greatereq(smallest->getValue(),val))
  33.             return nullptr;
  34.         auto currentNode = smallest;
  35.         while (true)
  36.         {
  37.             auto next = currentNode->getNextBiggest();
  38.             if (next == nullptr)
  39.                 return currentNode;
  40.             if (greatereq(next->getValue(), val))
  41.                 return currentNode;
  42.             currentNode = currentNode->getNextBiggest();
  43.         }
  44.     }
  45.  
  46.     bool less(Type x, Type y) const { return cmpFn(x, y); }
  47.     bool greatereq(Type x, Type y) const { return !cmpFn(x, y); }
  48.     bool greater(Type x, Type y) const { return cmpFn(y, x); }
  49.     bool lesseq(Type x, Type y) const { return !cmpFn(y, x); }
  50.     SmartList&& buildCopy() const
  51.     {
  52.         auto items = getStack();
  53.         SmartList copy;
  54.         for (auto it = rbegin(items); it < rend(items); ++it)
  55.         {
  56.             copy.push(*it);
  57.         }
  58.         return std::move(copy);
  59.     }
  60. public:
  61.     SmartList(Compare comparisonFunction = std::less<Type>()) : cmpFn(comparisonFunction), smallest(nullptr), newest(nullptr) {}
  62.     SmartList(SmartList&& list) : cmpFn(list.cmpFn), smallest(list.smallest), newest(list.newest)
  63.     {
  64.         list.smallest = nullptr;
  65.         list.newest = nullptr;
  66.     }
  67.     SmartList(const SmartList& list) : SmartList(buildCopy()) {}
  68.     ~SmartList()
  69.     {
  70.         auto current = newest;
  71.         while (current != nullptr)
  72.         {
  73.             auto next = current->getNextNewest();
  74.             delete current;
  75.             current = next;
  76.         }
  77.     }
  78.  
  79.     void push(const Type& val)
  80.     {
  81.         std::lock_guard<std::mutex> guard(lock);
  82.         auto nextSmallest = getLargestSmallerThan(val);
  83.         auto nextBiggest = nextSmallest == nullptr ? smallest : nextSmallest->getNextBiggest();
  84.         auto newNode = new Node(val, newest, nextBiggest);
  85.         if (nextSmallest != nullptr)
  86.         {
  87.             nextSmallest->setNextBiggest(newNode);
  88.         }
  89.         else
  90.         {
  91.             smallest = newNode;
  92.         }
  93.         newest = newNode;
  94.     }
  95.  
  96.     Type pop()
  97.     {
  98.         std::lock_guard<std::mutex> guard(lock);
  99.         Type ret = newest->getValue();
  100.         auto nextSmallest = getLargestSmallerThan(ret);
  101.         if (nextSmallest != nullptr)
  102.         {
  103.             nextSmallest->setNextBiggest(newest->getNextBiggest());
  104.         }
  105.         else
  106.         {
  107.             smallest = smallest->getNextBiggest();
  108.         }
  109.         auto newNewest = newest->getNextNewest();
  110.         delete newest;
  111.         newest = newNewest;
  112.         return ret;
  113.     }
  114.  
  115.     size_t size() const
  116.     {
  117.         std::lock_guard<std::mutex> guard(lock);
  118.         auto current = newest;
  119.         size_t size = 0;
  120.         while (current != nullptr)
  121.         {
  122.             current = current->getNextNewest();
  123.             ++size;
  124.         }
  125.         return size;
  126.     }
  127.  
  128.     Type head() const
  129.     {
  130.         return newest->getValue();
  131.     }
  132.  
  133.     void removeGreater(const Type& val)
  134.     {
  135.         std::lock_guard<std::mutex> guard(lock);
  136.         if (smallest == nullptr) // There is nothing to be removed.
  137.         {
  138.             return;
  139.         }
  140.         auto newLargest = smallest;
  141.         while (true)
  142.         {
  143.             auto nextLargest = newLargest->getNextBiggest();
  144.             if (nextLargest == nullptr) // No values are removed.
  145.             {
  146.                 return;
  147.             }
  148.             if (greater(nextLargest->getValue(), val))
  149.             {
  150.                 break;
  151.             }
  152.             newLargest = nextLargest;
  153.         }
  154.         newLargest->setNextBiggest(nullptr);
  155.  
  156.         // Now go through and remove all the values.
  157.         auto current = newest;
  158.  
  159.         // First find the new newest value.
  160.         while (current != nullptr && greater(current->getValue(), val))
  161.         {
  162.             newest = current->getNextNewest();
  163.             delete current;
  164.             current = newest;
  165.         }
  166.  
  167.         // Now go remove the rest of them.
  168.         while (current != nullptr && current->getNextNewest() != nullptr)
  169.         {
  170.             auto next = current->getNextNewest();
  171.             if (greater(next->getValue(), val))
  172.             {
  173.                 current->setNextNewest(next->getNextNewest());
  174.                 delete next;
  175.             }
  176.             else
  177.             {
  178.                 current = next;
  179.             }
  180.         }
  181.         return;
  182.     }
  183.  
  184.     std::vector<Type> getStack() const
  185.     {
  186.         std::lock_guard<std::mutex> guard(lock);
  187.         auto current = newest;
  188.         std::vector<Type> ret;
  189.         while (current != nullptr)
  190.         {
  191.             ret.push_back(current->getValue());
  192.             current = current->getNextNewest();
  193.         }
  194.         return ret;
  195.     }
  196.  
  197.     std::vector<Type> getSorted() const
  198.     {
  199.         std::lock_guard<std::mutex> guard(lock);
  200.         auto current = smallest;
  201.         std::vector<Type> ret;
  202.         while (current != nullptr)
  203.         {
  204.             ret.push_back(current->getValue());
  205.             current = current->getNextBiggest();
  206.         }
  207.         return ret;
  208.     }
  209. };
  210.  
  211. // main.cpp
  212.  
  213. #include <random>
  214. #include <iostream>
  215. #include <chrono>
  216.  
  217. //#include "smartlinkedlist.h"
  218.  
  219. std::default_random_engine generator;
  220.  
  221. int getRandomNumber(int min, int max)
  222. {
  223.     std::uniform_int_distribution<int> n_maker(min, max);
  224.     return n_maker(generator);
  225. }
  226.  
  227. template <typename Container>
  228. void displayContainer(const Container& in)
  229. {
  230.     for (const auto& val : in)
  231.     {
  232.         std::cout << val << '\n';
  233.     }
  234.     return;
  235. }
  236.  
  237. template <class List>
  238. void viewList(const List& list)
  239. {
  240.     std::cout << "Stack view:\n";
  241.     displayContainer(list.getStack());
  242.     std::cout << "\nSorted view:\n";
  243.     displayContainer(list.getSorted());
  244. }
  245.  
  246. int main()
  247. {
  248.     generator.seed(std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count());
  249.     const int n = getRandomNumber(1, 40);
  250.     SmartList<int> list;
  251.  
  252.     std::cout << "Setup list with size " << n << '\n';
  253.     for (int i(0); i<n; ++i)
  254.     {
  255.         const auto value = getRandomNumber(-1000, 1000);
  256.         std::cout << "Push value " << value << '\n';
  257.         list.push(value);
  258.     }
  259.  
  260.     std::cout << "Start\n";
  261.     viewList(list);
  262.  
  263.     const auto threshold = getRandomNumber(-1000, 1000);
  264.     std::cout << "Remove greater than " << threshold << '\n';
  265.     list.removeGreater(threshold);
  266.     viewList(list);
  267.  
  268.     std::cout << "Pop half\n";
  269.     const int size = list.size();
  270.     for (int i(0); i<size / 2; ++i)
  271.     {
  272.         std::cout << "Popped value " << list.pop() << '\n';
  273.     }
  274.  
  275.     viewList(list);
  276.     std::cin.get();
  277.     return 0;
  278. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement