Advertisement
Guest User

listsort.h

a guest
Oct 7th, 2014
56
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.43 KB | None | 0 0
  1. //  Written in 2014 by Ivo Doko (ivo.doko@gmail.com)
  2.  
  3. //  To the extent possible under law, the author has dedicated
  4. //  all copyright and related and neighboring rights to this
  5. //  software to the public domain worldwide. This software is
  6. //  distributed without any warranty.
  7.  
  8. //  See <http://creativecommons.org/publicdomain/zero/1.0/>.
  9.  
  10. #ifndef _LISTSORT_H
  11. #define _LISTSORT_H 1
  12.  
  13. #include <list>
  14. #include <algorithm>
  15.  
  16. template<typename T>
  17. void listsort(std::list<T>& lst)
  18. {
  19.     using lTi = typename std::list<T>::iterator;
  20.     std::list<lTi> boundaries;
  21.     lTi l{lst.begin()},
  22.         r{l};
  23.     //Progressively build sorted regions from
  24.     //ascending and descending runs until the
  25.     //end of the list is reached.
  26.     while(l != lst.end())
  27.     {
  28.         lTi li{l};
  29.         ++li;
  30.         while(li != lst.end())
  31.         {
  32.             //li is always one place ahead of r,
  33.             //so in this case just move r one
  34.             //place forward.
  35.             if(*li >= *r) { ++r; ++li; }
  36.             else
  37.                 //Place values smaller than *l before
  38.                 //l and change l to point to the new
  39.                 //minimum.
  40.                 if(*li < *l)
  41.                 {
  42.                     lTi moved{li++};
  43.                     lst.splice(l, lst, moved);
  44.                     --l;
  45.                 }
  46.                 //If the value can't be placed neither
  47.                 //before l nor after r, stop building
  48.                 //the current region.
  49.                 else break;
  50.         }
  51.         //Add l to the list of region boundaries and
  52.         //continue with building the following region.
  53.         boundaries.emplace_back(l);
  54.         l = ++r;
  55.     }
  56.     //Add the end of the list as the final region boundary.
  57.     boundaries.emplace_back(lst.end());
  58.     //Merge pairs of adjacent regions until only two
  59.     //boundaries remain - lst.begin() and lst.end().
  60.     using lBi = typename std::list<lTi>::iterator;
  61.     while(boundaries.size() > 2)
  62.     {
  63.         lBi ri{boundaries.begin()};
  64.         while(*ri != lst.end())
  65.         {
  66.             lBi ri_a{ri++};
  67.             if(*ri == lst.end()) break;
  68.             lBi ri_b{ri++};
  69.             //Merge regions [*ri_a, *ri_b) and [*ri_b, *ri)
  70.             //and then remove ri_b from the list of region
  71.             //boundaries.
  72.             std::inplace_merge(*ri_a, *ri_b, *ri);
  73.             boundaries.erase(ri_b);
  74.         }
  75.     }
  76. }
  77.  
  78. #endif // _LISTSORT_H
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement