Sorting
Quick Sort (Lomuto)
Choose the last item as a pivot, partition smaller values to its left, then recurse on the two sides.
Algorithm
The checked-in replay follows the same small input and final output across all 21 DSA books, so this Bash DSA implementation can be compared directly with the other languages.
pivot
The final element is moved to the boundary between smaller and larger values.
partition
One scan rearranges the current range before the recursive calls.
Visual walkthrough
Basic Implementation
basic.sh
#!/usr/bin/env bash
set -euo pipefail
partition() {
local low=$1
local high=$2
local pivot=${arr[high]}
local i=$((low - 1))
local j
local tmp
for ((j = low; j < high; j++)); do
if ((arr[j] <= pivot)); then
i=$((i + 1))
tmp=${arr[i]}
arr[i]=${arr[j]}
arr[j]=$tmp
fi
done
tmp=${arr[i+1]}
arr[i+1]=${arr[high]}
arr[high]=$tmp
pivot_index=$((i + 1))
}
quick_sort() {
local low=$1
local high=$2
if ((low < high)); then
partition "$low" "$high"
local p=$pivot_index
quick_sort "$low" "$((p - 1))"
quick_sort "$((p + 1))" "$high"
fi
}
arr=(4 1 5 2 3)
pivot_index=0
quick_sort 0 $((${#arr[@]} - 1))
printf '['
sep=''
for v in "${arr[@]}"; do
printf '%s%d' "$sep" "$v"
sep=', '
done
printf ']\n'
Complexity
- Time: O(n^2) worst, O(n log n) average
- Space: O(log n) average call stack
- Stable: no
Implementation notes
arr=(4 1 5 2 3)is the pinned Bash indexed array, andquick_sortmutates it in place by index.quick_sort "$low" "$high"receives integer bounds.if ((low < high))is Bash arithmetic evaluation for the recursive base case.partition "$low" "$high"chooses the last element as the pivot withpivot=${arr[high]}.i=$((low - 1))marks the end of the smaller-or-equal region. The scan variablejwalks fromlowtohigh - 1.if ((arr[j] <= pivot)); thenis a numeric comparison. When it passes,imoves right and thetmplines swaparr[i]witharr[j].- After the scan, another
tmpswap moves the pivot intoarr[i+1], andpivot_index=$((i + 1))tellsquick_sortwhere to split. - The recursive calls sort
low..p-1andp+1..high. Lomuto quicksort is not stable because swaps can move equal values around.
First partition replay
pivot 3 in [4, 1, 5, 2, 3]
4 > 3: keep right side
1 <= 3: swap into left side -> [1, 4, 5, 2, 3]
5 > 3: keep right side
2 <= 3: swap into left side -> [1, 2, 5, 4, 3]
pivot swap: [1, 2, 3, 4, 5]
- Final output uses the shared Bash formatter:
printf '[',for v in "${arr[@]}",printf '%s%d' "$sep" "$v", andprintf ']\n'.