В этом небольшом посте, я выкладываю тривиальные реализации различных методов сортировки массивов с разными типами данных. Все предложенные способы сортируют массивы по возрастанию (хотя, очень легко сделать так, чтобы весь код стал универсальным: допустим, можно слегка модифицировать листинги таким образом, чтобы каждая из функций сортировки принимала на вход еще и операцию, с помощью которой будет выполнено упорядочивание).
Итак, код на D:
import std.stdio; void exch(T)(ref T x, ref T y) { T tmp = x; x = y; y = tmp; } T[] selectionSort(T)(T[] x) { T[] res = x.dup; for (size_t i = 0; i < res.length - 1; i++) { size_t min = i; for (size_t j = i + 1; j < res.length; j++) { if (res[j] < res[min]) min = j; } exch(res[i],res[min]); } return res; } T[] bubbleSort(T)(T[] x) { T[] res = x.dup; for (size_t i = 0; i < res.length; i++) { for (size_t j = 0; j < res.length - i - 1; j++) { if (res[j] > res[j+1]) exch(res[j],res[j+1]); } } return res; } T[] shellSort(T)(T[] x) { T[] res = x.dup; size_t d = x.length; for (size_t i = d/2; i > 0; i /= 2) { for (size_t j = i; j < d; j++) { for (size_t k = j; k >= i && res[k-i] > res[k]; k -= i) { exch(res[k],res[k-i]); } } } return res; } T[] gnomeSort(T)(T[] x) { T[] res = x.dup; size_t i = 0; while (i < res.length) { if (i == 0 || res[i-1] <= res[i]) i++; else { exch(res[i],res[i-1]); i--; } } return res; } T[] insertionSort(T)(T[] x) { T[] res = x.dup; for (size_t i = 0; i < res.length; i++) { for (size_t j = i; j && res[j] < res[j-1]; j--) { exch(res[j],res[j-1]); } } return res; } T[] shakerSort(T)(T[] x) { T[] res = x.dup; size_t beg,end; for (size_t i = 0; i < res.length/2; i++) { beg = 0; end = res.length - 1; do { if (res[beg] > res[beg+1]) exch(res[beg],res[beg+1]); beg++; if (res[end-1] > res[end]) exch(res[end-1],res[end]); end--; } while (beg <= end); } return res; } T[] combSort(T)(T[] x) { T[] res = x.dup; size_t size = res.length; if (res && size) { size_t jump = size; bool swapped = true; while (jump > 1 || swapped) { if (jump > 1) jump /= 1.24733; swapped = false; for (size_t i = 0; i + jump < size; i++) { if (res[i+jump] < res[i]) { exch(res[i+jump],res[i]); swapped = true; } } } } return res; } T[] oddEvenSort(T)(T[] x) { T[] res = x.dup; bool sorted = false; template cycle(string num) { const char[] cycle = "for (int i = " ~ num ~ " ; i < res.length - 1; i += 2) { if (res[i] > res[i+1]) { exch(res[i],res[i+1]); sorted = false; } }"; } while (!sorted) { sorted = true; mixin(cycle!"1"); mixin(cycle!"0"); } return res; } T[] stoogeSort(T)(ref T[] x,size_t i, size_t j) { // first call: stoogeSort(x,0,x.length - 1) if (x[j] < x[i]) exch(x[j],x[i]); if (j - i > 1) { size_t t = (j - i + 1) / 3; stoogeSort(x, i , j-t); stoogeSort(x, i+t, j ); stoogeSort(x, i , j-t); } return x; } T[] quickSort(T)(T[] x) { uint partition(T)(T[] x) { if (x.length < 2) return 0; auto pivot = x[$-1]; uint i = -1, j = x.length-1; while(i < j || i == -1) { i++; while(x[i] < pivot) i++; j--; while(i < j && x[j] > pivot) j--; if(i < j && j < x.length) exch(x[i], x[j]); } exch(x[i], x[$-1]); return i; } if (x.length > 1) { exch(x[$/2], x[$-1]); auto p = partition(x); quickSort(x[0 .. p]); quickSort(x[p + 1 .. $]); } return x; }
Процедура exch — вспомогательная и служит для того, чтобы поменять значения некоторых двух переменных местами.
P.S: Код, конечно, не идеальный, но все-таки он написан мной. Кроме того, возможно, я выложу более универсальную версию данных алгоритмов.