// input: a - array of integers; l,r - leftmost and rightmost indexes
// output: final index of pivot M; array reorganised
partition(a, l, r){
i = l + 1;
j = r;
m = a[l]; // pivot = leftmost element
temp;
do{
while((i < r) && (a[i] <= m)) i++;
while((j > i) && (a[j] >= m)) j--;
if(i < j) {temp = a[i]; a[i] = a[j]; a[j] = temp;}
}while(i < j);
// when (i==r):
if(a[i] > m) {a[l] = a[i - 1]; a[i - 1] = m; return i - 1;}
else {a[l] = a[i]; a[i] = m; return i;}
}
Hoare's partition scheme โ two inward-moving pointers, leftmost element as
pivot. O(1) extra space.
// input: a - array of integers; l,r - leftmost and rightmost indexes
// (the procedure does not return anything)
quicksort(a, l, r){
if(l >= r) return;
k = partition(a, l, r);
quicksort(a, l, k - 1);
quicksort(a, k + 1, r);
}
Divide and conquer approach by C.A.R. Hoare. Space: O(n) worst case, O(log n)
average (recursion stack).
// input: a - array of non-negative integers; l - its length
countSort(a, l){
max = maxValue(a, l);
l1 = max + 1;
counts[l1]; // allocate counts array
result[l]; // allocate result array
for(i = 0; i < l1; i++) counts[i] = 0;
for(i = 0; i < l; i++) counts[a[i]]++;
for(i = 1; i < l1; i++) counts[i] += counts[i - 1];
for(i = l - 1; i >= 0; i--)
result[--counts[a[i]]] = a[i];
}
Based on direct addressing. Does NOT use comparisons. Pre-decrementation in
the last line avoids shifting. Requires ฮ(n + max) space.
// RadixSort is a scheme, not a single algorithm.
// It applies a stable internal sorting algorithm
// to consecutive positions starting from the LAST position.
radixSort(a, len, d): // d = number of positions (e.g. digits)
for(pos = d - 1; pos >= 0; pos--)
stableSort(a, len, by position pos)
// e.g. countSort on the digit at position pos
Ideal for lexicographic sort of fixed-length objects (strings, multi-digit
numbers). Uses any stable sort as internal algorithm โ CountSort is a natural choice.