Sorting
Quick Sort (Lomuto)
Choose the last item as a pivot, partition smaller values to its left, then recurse on the two sides.
Algorithm
Basic Implementation
basic.pl
use strict; use warnings;
sub partition {
my ($arr, $low, $high) = @_;
my $pivot = $arr->[$high];
my $i = $low - 1;
for (my $j = $low; $j < $high; $j++) {
if ($arr->[$j] <= $pivot) {
$i++;
@$arr[$i, $j] = @$arr[$j, $i];
}
}
@$arr[$i + 1, $high] = @$arr[$high, $i + 1];
return $i + 1;
}
sub quick_sort {
my ($arr, $low, $high) = @_;
if ($low < $high) {
my $pivot_index = partition($arr, $low, $high);
quick_sort($arr, $low, $pivot_index - 1);
quick_sort($arr, $pivot_index + 1, $high);
}
}
my @arr = (4, 1, 5, 2, 3);
quick_sort(\@arr, 0, $#arr);
print "[" . join(", ", @arr) . "]
";
Complexity
- Time: O(n^2) worst, O(n log n) average
- Space: O(log n) average call stack
- Stable: no
Implementation notes
my @arr = (4, 1, 5, 2, 3)declares the pinned Perl array with the@sigil.quick_sort(\@arr, 0, $#arr)passes an array reference plus zero-based bounds;$#arris the last valid index.partitionunpacks its parameters withmy ($arr, $low, $high) = @_, so$arris a scalar reference to the array.- Array elements are read through the reference, such as
$arr->[$high]and$arr->[$j]. - Lomuto pivot selection is
my $pivot = $arr->[$high], so the first pivot is the final value3. my $i = $low - 1starts the smaller-value boundary at-1for the first partition.- The partition scan is
for (my $j = $low; $j < $high; $j++), so it compares indexes0through3and leaves the pivot at index4until the final placement. - The comparison is numeric and inclusive:
if ($arr->[$j] <= $pivot). - Swaps use Perl slice/list assignment on the referenced array:
@$arr[$i, $j] = @$arr[$j, $i]. - In the trace,
4 <= 3is false, so4stays on the right side andiremains-1. 1 <= 3is true, soibecomes0and the array changes to[1, 4, 5, 2, 3].5 <= 3is false, leaving[1, 4, 5, 2, 3].2 <= 3is true, soibecomes1and the array changes to[1, 2, 5, 4, 3].- Final pivot placement uses another slice assignment:
@$arr[$i + 1, $high] = @$arr[$high, $i + 1], putting3at index2and producing[1, 2, 3, 4, 5]. quick_sortrecurses only when$low < $high; the replay then summarizes the already-sorted left side[1, 2]and right side[4, 5]instead of expanding every base-case call.- The final
printconcatenates"[",join(", ", @arr), and a closing bracket string that includes the newline, producing[1, 2, 3, 4, 5].
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.