mn_sort.hpp
Go to the documentation of this file.
1 
19 #ifndef MINLIB_STL_SORT_H_
20 #define MINLIB_STL_SORT_H_
21 
22 #include "mn_utils.hpp"
23 
24 
25 namespace mn {
26  namespace internal {
27 
28  MN_TEMPLATE_FULL_DECL_TWO(typename, T, class, TPredicate)
29  void quick_sort(T* data, long low, long high, TPredicate pred) {
30  while (true) {
31  long i = low;
32  long j = high;
33  const T pivot = data[(low + high) >> 1];
34 
35  do {
36  while (pred(data[i], pivot)) ++i;
37  while (pred(pivot, data[j])) --j;
38 
39  // Anything to swap?
40  if (j >= i) {
41  if (i != j) {
42  // Swap
43  T tmp(data[i]);
44  data[i] = data[j];
45  data[j] = tmp;
46  }
47  ++i;
48  --j;
49  }
50  } while (i <= j);
51 
52  if (low < j) quick_sort(data, low, j, pred);
53  if (i < high) low = i;
54  else break;
55  }
56  }
57 
58  MN_TEMPLATE_FULL_DECL_TWO(typename, T, class, TPredicate)
59  void down_heap(T* data, size_t k, size_t n, TPredicate pred) {
60  const T temp = data[k - 1];
61 
62  while (k <= n / 2) {
63  size_t child = 2 * k;
64  if (child < n && pred(data[child - 1], data[child]))
65  ++child;
66  if (pred(temp, data[child - 1])) {
67  data[k - 1] = data[child - 1];
68  k = child;
69  } else break;
70  }
71  data[k - 1] = temp;
72  }
73 
74  MN_TEMPLATE_FULL_DECL_TWO(typename, T, class, TPredicate)
75  void shell_sort(T* data, size_t n, TPredicate pred) {
76  size_t temp, j;
77 
78  for (size_t gap = n/2; gap > 0; gap /= 2) {
79  for (size_t i = gap; i < n; i += 1) {
80  temp = data[i];
81 
82  for (j = i; j >= gap && pred(arr[j - gap], temp); j -= gap) {
83  data[j] = data[j - gap];
84  }
85  data[j] = temp;
86  }
87  }
88  }
89  } // internal
90 
91  MN_TEMPLATE_FULL_DECL_TWO(typename, T, class, TPredicate)
92  void insertion_sort(T* begin, T* end, TPredicate pred) {
93  const size_t num = end - begin;
94 
95  for (size_t i = 0; i < num; ++i) {
96  const T t = begin[i];
97  size_t j = i;
98 
99  while (j > 0 && pred(t, begin[j - 1])) {
100  begin[j] = begin[j - 1];
101  --j;
102  }
103  begin[j] = t;
104  }
105  }
106  MN_TEMPLATE_FULL_DECL_ONE(typename, T)
107  void insertion_sort(T* begin, T* end) {
108  insertion_sort(begin, end, less<T>());
109  }
110 
111  MN_TEMPLATE_FULL_DECL_TWO(typename, T, class, TPredicate)
112  void shell_sort(T* begin, T* end, TPredicate pred) {
113  if (end - begin > 1)
114  internal::shell_sort(begin, (size_t)(end - begin), pred);
115  }
116 
117  MN_TEMPLATE_FULL_DECL_ONE(typename, T)
118  void shell_sort(T* begin, T* end) {
119  shell_sort(begin, end, mn::greater<T>());
120  }
121 
122 
123  MN_TEMPLATE_FULL_DECL_TWO(typename, T, class, TPredicate)
124  void quick_sort(T* begin, T* end, TPredicate pred) {
125  if (end - begin > 1)
126  internal::quick_sort(begin, 0, (size_t)(end - begin - 1), pred);
127  }
128 
129  MN_TEMPLATE_FULL_DECL_ONE(typename, T)
130  void quick_sort(T* begin, T* end) {
131  quick_sort(begin, end, less<T>());
132  }
133 
134  MN_TEMPLATE_FULL_DECL_TWO(typename, T, class, TPredicate)
135  void heap_sort(T* begin, T* end, TPredicate pred) {
136 
137  size_t n = end - begin;
138  for (size_t k = n / 2; k != 0; --k)
139  internal::down_heap(begin, k, n, pred);
140 
141  while (n >= 1) {
142  const T temp = begin[0];
143  begin[0] = begin[n - 1];
144  begin[n - 1] = temp;
145 
146  --n;
147  internal::down_heap(begin, 1, n, pred);
148  }
149  }
150 
151  MN_TEMPLATE_FULL_DECL_ONE(typename, T)
152  void heap_sort(T* begin, T* end) {
153  heap_sort(begin, end, mn::less<T>());
154  }
155 
156  MN_TEMPLATE_FULL_DECL_TWO(typename, TIter, typename, TPredicate)
157  bool is_sorted(TIter begin, TIter end, TPredicate pred) {
158  TIter it = begin;
159  TIter it_prev = it;
160  bool is_sorted = true;
161 
162  while (it != end) {
163  if (it_prev != it) {
164  if (pred(*it, *it_prev)) {
165  is_sorted = false;
166  break;
167  }
168  }
169  it_prev = it;
170  ++it;
171  }
172  return is_sorted;
173  }
174 
175  MN_TEMPLATE_FULL_DECL_TWO(typename, T, class, TPredicate)
176  void sort(T* begin, T* end, TPredicate pred) {
177  shell_sort(begin, end, pred);
178  }
179 
180  MN_TEMPLATE_FULL_DECL_ONE(typename, T)
181  void sort(T* begin, T* end) {
182  shell_sort(begin, end, mn::greater<T>());
183  }
184 
185 
186 }
187 
188 #endif
#define MN_TEMPLATE_FULL_DECL_ONE(d1, t1)
Definition: mn_defines.hpp:25
#define MN_TEMPLATE_FULL_DECL_TWO(d1, t1, d2, t2)
Definition: mn_defines.hpp:26
void quick_sort(T *data, long low, long high, TPredicate pred)
Definition: mn_sort.hpp:29
void down_heap(T *data, size_t k, size_t n, TPredicate pred)
Definition: mn_sort.hpp:59
void shell_sort(T *data, size_t n, TPredicate pred)
Definition: mn_sort.hpp:75
struct mn::memory::detail::ptr_difference T
Definition: mn_atomic_singleton.hpp:38
Definition: mn_allocator_typetraits.hpp:25
void heap_sort(T *begin, T *end, TPredicate pred)
Definition: mn_sort.hpp:135
bool is_sorted(TIter begin, TIter end, TPredicate pred)
Definition: mn_sort.hpp:157
void quick_sort(T *begin, T *end, TPredicate pred)
Definition: mn_sort.hpp:124
void shell_sort(T *begin, T *end, TPredicate pred)
Definition: mn_sort.hpp:112
void insertion_sort(T *begin, T *end, TPredicate pred)
Definition: mn_sort.hpp:92
void sort(T *begin, T *end, TPredicate pred)
Definition: mn_sort.hpp:176
Definition: mn_utils.hpp:181
Definition: mn_utils.hpp:175