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.

74 lines
2.4 KiB

  1. #pragma once
  2. #include <gp/algorithms/move.hpp>
  3. #include <gp/algorithms/partition.hpp>
  4. #include <iostream>
  5. namespace gp {
  6. namespace __details {
  7. template<typename it_t, typename pred>
  8. void selection_sort(it_t first, it_t last, pred predicate = pred{}) {
  9. while(first != last) {
  10. it_t traveler = first;
  11. it_t it = first;
  12. it++;
  13. for(;it!=last;it++) {
  14. if(predicate(*it, *traveler)) traveler = it;
  15. }
  16. gp::swap(*first, *traveler);
  17. first++;
  18. }
  19. }
  20. template<typename it_t, typename pred>
  21. bool sort2(auto it0, auto it1, pred predicate = pred{}){
  22. if(it0 != it1 && predicate(*it1, *it0)) {
  23. gp::swap(*it0, *it1);
  24. return true;
  25. }
  26. return false;
  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. template<typename it_t, typename pred>
  44. void bubble_sort(it_t first, it_t last, pred predicate = pred{}) {
  45. if(last - first <= 2) {
  46. auto nit = first + (size_t)(last == first + 1);
  47. __details::sort2<it_t>(first, nit, predicate);
  48. return;
  49. }
  50. size_t swaps;
  51. do {
  52. swaps = 0;
  53. auto it = first;
  54. auto nit = it + 1;
  55. for(;;) {
  56. swaps += __details::sort2<it_t>(it, nit, predicate);
  57. ++it; ++nit;
  58. if(nit == last) break;
  59. }
  60. } while(swaps);
  61. }
  62. }
  63. template<typename it_t, typename pred>
  64. void sort(it_t first, it_t last, pred predicate = pred{}) {
  65. return gp::__details::bubble_sort(first, last, predicate);
  66. }
  67. }