General Purpose library for Freestanding C++ and POSIX systems
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

73 lines
2.4 KiB

  1. #pragma once
  2. #include <gp/algorithms/move.hpp>
  3. #include <gp/algorithms/partition.hpp>
  4. namespace gp {
  5. namespace __details {
  6. template<typename it_t, typename pred>
  7. void selection_sort(it_t first, it_t last, pred predicate = pred{}) {
  8. while(first != last) {
  9. it_t traveler = first;
  10. it_t it = first;
  11. it++;
  12. for(;it!=last;it++) {
  13. if(predicate(*it, *traveler)) traveler = it;
  14. }
  15. gp::swap(*first, *traveler);
  16. first++;
  17. }
  18. }
  19. template<typename it_t, typename pred>
  20. bool sort2(auto it0, auto it1, pred predicate = pred{}){
  21. if(it0 != it1 && predicate(*it1, *it0)) {
  22. gp::swap(*it0, *it1);
  23. return true;
  24. }
  25. return false;
  26. };
  27. /*
  28. template<typename it_t, typename pred>
  29. void quick_sort(it_t first, it_t last, pred predicate = pred{}) {
  30. using __details::sort2;
  31. if(last - first <= 2) {
  32. auto nit = first + (size_t)(last == first + 1);
  33. __details::sort2<it_t>(first, nit, predicate);
  34. return;
  35. }
  36. auto pivot_v = *(first + (last - first)/2);
  37. auto pivot = gp::partition(first, last, [&](auto& a) -> bool{
  38. return predicate(a, pivot_v);
  39. });
  40. gp::__details::quick_sort(first, pivot, predicate);
  41. gp::__details::quick_sort(pivot, last, predicate);
  42. }
  43. */
  44. template<typename it_t, typename pred>
  45. void bubble_sort(it_t first, it_t last, pred predicate = pred{}) {
  46. if(last - first <= 2) {
  47. auto nit = first + (size_t)(last == first + 1);
  48. __details::sort2<it_t>(first, nit, predicate);
  49. return;
  50. }
  51. size_t swaps;
  52. do {
  53. swaps = 0;
  54. auto it = first;
  55. auto nit = it + 1;
  56. for(;;) {
  57. swaps += __details::sort2<it_t>(it, nit, predicate);
  58. ++it; ++nit;
  59. if(nit == last) break;
  60. }
  61. } while(swaps);
  62. }
  63. }
  64. template<typename it_t, typename pred>
  65. void sort(it_t first, it_t last, pred predicate = pred{}) {
  66. return gp::__details::selection_sort(first, last, predicate);
  67. }
  68. }