Sorting
Selection Sort
Repeatedly scan the unsorted suffix for its minimum element, then swap
that minimum into the next position. After i passes, the prefix
arr[0..i-1] is the sorted order statistics.
Algorithm
Canonical input arr=(5 1 4 2 8) finishes after four passes; the
final array is [1, 2, 4, 5, 8].
Basic Implementation
basic.sql
.mode list
.headers off
WITH RECURSIVE sel(p, vals) AS (
SELECT 0, json_array(5, 1, 4, 2, 8)
UNION ALL
SELECT p + 1, json_set(
json_set(vals,
'$[' || p || ']',
json_extract(vals, '$[' ||
(SELECT key FROM json_each(sel.vals)
WHERE key >= sel.p
ORDER BY CAST(value AS INTEGER) ASC, key ASC LIMIT 1) || ']')),
'$[' ||
(SELECT key FROM json_each(sel.vals)
WHERE key >= sel.p
ORDER BY CAST(value AS INTEGER) ASC, key ASC LIMIT 1) || ']',
json_extract(vals, '$[' || p || ']'))
FROM sel WHERE p < 4
)
SELECT '[' || GROUP_CONCAT(value, ', ') || ']'
FROM json_each((SELECT vals FROM sel ORDER BY p DESC LIMIT 1));
Complexity
- Time: O(n^2)
- Space: O(n) for the per-step JSON snapshot in the recursive CTE
Implementation notes
- SQL: the array is held as a JSON1 array and a
WITH RECURSIVE sel(p, vals)CTE runs one pass per row. Inside each step a scalar subquery overjson_each(sel.vals)finds the minimum index in[p..n-1], and a pairedjson_setswap moves that minimum intovals[p]. - The
ORDER BY CAST(value AS INTEGER) ASC, key ASC LIMIT 1tie-breaker keeps the result deterministic when two slots tie on value; the canonical lesson input has no ties, so the rule fires but produces the same result either way. - Like
sort-bubble, the finalGROUP_CONCAT(value, ', ')over the last snapshot emits[1, 2, 4, 5, 8]so the printed output matches the language-neutral lesson spec exactly.
min pick
Each pass scans `arr[i..n-1]` to find the index of the smallest element.
settled prefix
After pass `i`, `arr[0..i]` is the sorted prefix and never moves again.