void Merge(SortArray& A, size_t lo, size_t mid, size_t hi) { // mark merge boundaries A.mark(lo); A.mark(mid,3); A.mark(hi-1); // allocate output std::vector<value_type> out(hi-lo); // merge size_t i = lo, j = mid, o = 0; // first and second halves while (i < mid && j < hi) { // copy out for fewer time steps value_type ai = A[i], aj = A[j]; out[o++] = (ai < aj ? (++i, ai) : (++j, aj)); } // copy rest while (i < mid) out[o++] = A[i++]; while (j < hi) out[o++] = A[j++]; ASSERT(o == hi-lo); A.unmark(mid); // copy back for (i = 0; i < hi-lo; ++i) A.set(lo + i, out[i]); A.unmark(lo); A.unmark(hi-1); }
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; }
// 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(); }
// 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); } }
// with extra item on stack void InsertionSort2(SortArray& A) { for (size_t i = 1; i < A.size(); ++i) { value_type tmp, key = A[i]; A.mark(i); ssize_t j = i - 1; while (j >= 0 && (tmp = A[j]) > key) { A.set(j + 1, tmp); j--; } A.set(j + 1, key); A.unmark(i); } }