The basic steps a a mergesort:
- Divide Step: If a given array A has zero or one element, just simply return; it is already sorted. Otherwise, split A[m .. n] into two subarrays A[m .. h] and A[h + 1 .. n], each containing about half of the elements of A[m .. n]. That is, h is the halfway point of A[m .. n].
- Conquer Step: Conquer by recursively sorting the two subarrays A[m .. h] and A[h + 1 .. n].
- Combine Step: Combine the elements back in A[m .. n] by merging the two sorted subarrays A[m .. h] and A[h + 1 .. n] into a sorted sequence.
Here is a perl implementation of mergesort, this only works for numbers
#!/usr/bin/perl use strict; use warnings; my @numbers=qw(8 7 6 5 4 3 2 1); print "numbers before mergesort\n"; print "@numbers\n"; msort_number(@numbers); print "numbers after mergesort:\n"; print "@numbers\n"; sub msort_number { my $size = @_; print "There are $size numbers\n"; mergesort_number(\@_, 0, $size); } sub mergesort_number { my ($aref, $begin, $end) = @_; my $size = $end - $begin; # The array size if ($size < 2) {return;} # One or zero element my $half = $begin + int($size/2); mergesort_number($aref, $begin, $half); # Divide and conquer on first half mergesort_number($aref, $half, $end); # Divide and conquer on second half # To be more efficient, we use in-place merging, passing array as reference for (my $i = $begin; $i < $half; $i++) { if ($$aref[$i] > $$aref[$half]) { my $v = $$aref[$i]; $$aref[$i] = $$aref[$half]; my $i = $half; # Merge the another half while ($i<$end-1 && $$aref[$i+1] < $v) { ($$aref[$i], $$aref[$i+1]) = ($$aref[$i+1], $$aref[$i]); ++$i; } $$aref[$i] = $v; } } # print "aref = @$aref, begin = $begin, end = $end, half = $half\n"; }
Reference: http://en.literateprograms.org/Merge_sort_%28Perl%29
No comments:
Post a Comment