void OddEvenSort(SortArray& A) { bool sorted = false; while (!sorted) { sorted = true; for (size_t i = 1; i < A.size()-1; i += 2) { if(A[i] > A[i+1]) { A.swap(i, i+1); sorted = false; } } for (size_t i = 0; i < A.size()-1; i += 2) { if(A[i] > A[i+1]) { A.swap(i, i+1); sorted = false; } } } }
size_t PartitionLL(SortArray& A, size_t lo, size_t hi) { // pick pivot and move to back size_t p = QuickSortSelectPivot(A, lo, hi); value_type pivot = A[p]; A.swap(p, hi-1); A.mark(hi-1); volatile ssize_t i = lo; A.watch(&i, 3); for (size_t j = lo; j < hi-1; ++j) { if (A[j] <= pivot) { A.swap(i, j); ++i; } } A.swap(i, hi-1); A.unmark(hi-1); A.unwatch_all(); return i; }
void CocktailShakerSort(SortArray& A) { size_t lo = 0, hi = A.size()-1, mov = lo; while (lo < hi) { for (size_t i = hi; i > lo; --i) { if (A[i-1] > A[i]) { A.swap(i-1, i); mov = i; } } lo = mov; for (size_t i = lo; i < hi; ++i) { if (A[i] > A[i+1]) { A.swap(i, i+1); mov = i; } } hi = mov; } }
void CombSort(SortArray& A) { const double shrink = 1.3; bool swapped = false; size_t gap = A.size(); while ((gap > 1) || swapped) { if (gap > 1) { gap = (size_t)((float)gap / shrink); } swapped = false; for (size_t i = 0; gap + i < A.size(); ++i) { if (A[i] > A[i + gap]) { A.swap(i, i+gap); swapped = true; } } } }
// swaps every time (keeps all values visible) void BinaryInsertionSort(SortArray& A) { for (size_t i = 1; i < A.size(); ++i) { value_type key = A[i]; A.mark(i); int lo = 0, hi = i; while (lo < hi) { int mid = (lo + hi) / 2; if (key <= A[mid]) hi = mid; else lo = mid + 1; } // item has to go into position lo ssize_t j = i - 1; while (j >= lo) { A.swap(j, j+1); j--; } A.unmark(i); } }
void SelectionSort(SortArray& A) { volatile ssize_t jMin = 0; A.watch(&jMin, 3); for (size_t i = 0; i < A.size()-1; ++i) { jMin = i; for (size_t j = i+1; j < A.size(); ++j) { if (A[j] < A[jMin]) { A.mark_swap(j, jMin); jMin = j; } } A.swap(i, jMin); // mark the last good element if (i > 0) A.unmark(i-1); A.mark(i); } A.unwatch_all(); }
void BubbleSort(SortArray& A) { for (size_t i = 0; i < A.size()-1; ++i) { for (size_t j = 0; j < A.size()-1 - i; ++j) { if (A[j] > A[j + 1]) { A.swap(j, j+1); } } } }
std::pair<ssize_t,ssize_t> PartitionTernaryLL(SortArray& A, ssize_t lo, ssize_t hi) { // pick pivot and swap to back ssize_t p = QuickSortSelectPivot(A, lo, hi); value_type pivot = A[p]; A.swap(p, hi-1); A.mark(hi-1); volatile ssize_t i = lo, k = hi-1; A.watch(&i, 3); for (ssize_t j = lo; j < k; ++j) { int cmp = A[j].cmp(pivot); // ternary comparison if (cmp == 0) { A.swap(--k, j); --j; // reclassify A[j] A.mark(k,4); } else if (cmp < 0) { A.swap(i++, j); } } // unwatch i, because the pivot is swapped there // in the first step of the following swap loop. A.unwatch_all(); ssize_t j = i + (hi-k); for (ssize_t s = 0; s < hi-k; ++s) { A.swap(i+s, hi-1-s); A.mark_swap(i+s, hi-1-s); } A.unmark_all(); return std::make_pair(i,j); }
void GnomeSort(SortArray& A) { for (size_t i = 1; i < A.size(); ) { if (A[i] >= A[i-1]) { ++i; } else { A.swap(i, i-1); if (i > 1) --i; } } }
// swaps every time (keeps all values visible) void InsertionSort(SortArray& A) { for (size_t i = 1; i < A.size(); ++i) { value_type key = A[i]; A.mark(i); ssize_t j = i - 1; while (j >= 0 && A[j] > key) { A.swap(j, j+1); j--; } A.unmark(i); } }
void QuickSortLR(SortArray& A, ssize_t lo, ssize_t hi) { // pick pivot and watch volatile ssize_t p = QuickSortSelectPivot(A, lo, hi+1); value_type pivot = A[p]; A.watch(&p, 2); volatile ssize_t i = lo, j = hi; A.watch(&i, 3); A.watch(&j, 3); while (i <= j) { while (A[i] < pivot) i++; while (A[j] > pivot) j--; if (i <= j) { A.swap(i,j); // follow pivot if it is swapped if (p == i) p = j; else if (p == j) p = i; i++, j--; } } A.unwatch_all(); if (lo < j) QuickSortLR(A, lo, j); if (i < hi) QuickSortLR(A, i, hi); }
void QuickSortTernaryLR(SortArray& A, ssize_t lo, ssize_t hi) { if (hi <= lo) return; int cmp; // pick pivot and swap to back ssize_t piv = QuickSortSelectPivot(A, lo, hi+1); A.swap(piv, hi); A.mark(hi); const value_type& pivot = A[hi]; // schema: |p === |i <<< | ??? |j >>> |q === |piv volatile ssize_t i = lo, j = hi-1; volatile ssize_t p = lo, q = hi-1; A.watch(&i, 3); A.watch(&j, 3); for (;;) { // partition on left while (i <= j && (cmp = A[i].cmp(pivot)) <= 0) { if (cmp == 0) { A.mark(p,4); A.swap(i, p++); } ++i; } // partition on right while (i <= j && (cmp = A[j].cmp(pivot)) >= 0) { if (cmp == 0) { A.mark(q,4); A.swap(j, q--); } --j; } if (i > j) break; // swap item between < > regions A.swap(i++, j--); } // swap pivot to right place A.swap(i,hi); A.mark_swap(i,hi); ssize_t num_less = i - p; ssize_t num_greater = q - j; // swap equal ranges into center, but avoid swapping equal elements j = i-1; i = i+1; ssize_t pe = lo + std::min(p-lo, num_less); for (ssize_t k = lo; k < pe; k++, j--) { A.swap(k,j); A.mark_swap(k,j); } ssize_t qe = hi-1 - std::min(hi-1-q, num_greater-1); // one already greater at end for (ssize_t k = hi-1; k > qe; k--, i++) { A.swap(i,k); A.mark_swap(i,k); } A.unwatch_all(); A.unmark_all(); QuickSortTernaryLR(A, lo, lo + num_less - 1); QuickSortTernaryLR(A, hi - num_greater + 1, hi); }