Мне нужно реализовать быструю сортировку в SML для домашнего задания, и я заблудился. Ранее я был незнаком с тем, как реализована быстрая сортировка, поэтому я прочитал об этом, но каждая реализация, о которой я читал, была обязательной. Это не выглядит слишком сложно, но я понятия не имел, как функционально реализовать быструю сортировку.
В Wikipedia есть код быстрой сортировки в Standard ML (это язык, необходимый для моего задания), но я не понимаю, как он работает.
Код Википедии:
val filt = List.filter
fun quicksort << xs = let
fun qs [] = []
| qs [x] = [x]
| qs (p::xs) = let
val lessThanP = (fn x => << (x, p))
in
qs (filt lessThanP xs) @ p :: (qs (filt (not o lessThanP) xs))
end
in
qs xs
end
В частности, я не понимаю эту строку: qs (filt lessThanP xs) @ p :: (qs (filt (not o lessThanP) xs))
. Фильтр вернет список всего в xs меньше p *, который объединяется с p, который добавляется во все> = p. *
* при условии, что функция << (x, p) возвращает true, когда x <p. Конечно, это не должно быть так. </p>
На самом деле, печатать это помогает мне немного понять, что происходит. В любом случае, я пытаюсь сравнить эту функцию SML с псевдокодом быстрой сортировки вики, который следует.
функция быстрой сортировки (массив, «влево», «вправо»)
// If the list has 2 or more items
if 'left' < 'right'
// See "Choice of pivot" section below for possible choices
choose any 'pivotIndex' such that 'left' ≤ 'pivotIndex' ≤ 'right'
// Get lists of bigger and smaller items and final position of pivot
'pivotNewIndex' := partition(array, 'left', 'right', 'pivotIndex')
// Recursively sort elements smaller than the pivot
quicksort(array, 'left', 'pivotNewIndex' - 1)
// Recursively sort elements at least as big as the pivot
quicksort(array, 'pivotNewIndex' + 1, 'right')
Где раздел определен как
// left is the index of the leftmost element of the array
// right is the index of the rightmost element of the array (inclusive)
// number of elements in subarray = right-left+1
function partition(array, 'left', 'right', 'pivotIndex')
'pivotValue' := array['pivotIndex']
swap array['pivotIndex'] and array['right'] // Move pivot to end
'storeIndex' := 'left'
for 'i' from 'left' to 'right' - 1 // left ≤ i < right
if array['i'] < 'pivotValue'
swap array['i'] and array['storeIndex']
'storeIndex' := 'storeIndex' + 1
swap array['storeIndex'] and array['right'] // Move pivot to its final place
return 'storeIndex'
Итак, где именно происходит разбиение? Или я неправильно думаю о быстрой сортировке SML?