Sorting
Merge Sort (Top-Down)
Split the array recursively, sort each half, then merge two sorted runs into one sorted result.
Algorithm
The checked-in replay follows the same small input and final output across all 21 DSA books, so this Perl DSA implementation can be compared directly with the other languages.
divide and conquer
Each recursive call solves a smaller sorted subproblem.
merge step
Two sorted halves are combined by repeatedly taking the smaller front item.
Visual walkthrough
Basic Implementation
basic.pl
use strict; use warnings;
sub merge_sort {
my @values = @_;
return @values if @values <= 1;
my $mid = int(@values / 2);
my @left = merge_sort(@values[0 .. $mid - 1]);
my @right = merge_sort(@values[$mid .. $#values]);
my @merged;
while (@left && @right) {
push @merged, ($left[0] <= $right[0]) ? shift @left : shift @right;
}
return (@merged, @left, @right);
}
my @arr = merge_sort(5, 1, 4, 2, 8);
print "[" . join(", ", @arr) . "]
";
Complexity
- Time: O(n log n)
- Space: O(n)
- Stable: yes
Implementation notes
sub merge_sortreceives its input as the argument list@_, then copies it intomy @values = @_.- Perl arrays use the
@sigil here:@values,@left,@right,@merged, and the final@arr. - The base case is
return @values if @values <= 1; in that numeric comparison,@valuesis in scalar context, so it means the list length. my $mid = int(@values / 2)uses integer truncation to split the current list.- The recursive calls use Perl slice syntax:
@values[0 .. $mid - 1]for the left half and@values[$mid .. $#values]for the right half. - The checked input is passed as a list in
my @arr = merge_sort(5, 1, 4, 2, 8). - The trace shows the first split as left
[5, 1]and right[4, 2, 8]. - Recursive calls return sorted lists, so the replay then has left
[1, 5]and right[2, 4, 8]. my @mergedholds the output during the merge.- The merge loop runs while both halves still have elements:
while (@left && @right). - The comparison is numeric and stable on ties:
($left[0] <= $right[0]) ? shift @left : shift @right. shiftremoves the chosen front value from@leftor@right, andpush @merged, ...appends it to the merged result.return (@merged, @left, @right)appends whichever half still has leftover values after the loop.- The final replayed merge returns
[1, 2, 4, 5, 8]. - The final
printconcatenates"[",join(", ", @arr), and a closing bracket string that includes the newline, producing[1, 2, 4, 5, 8].