Perlでマージソート

wikipediarubyの例をPerlにしただけ。最初にリストを分割するのに再帰をしているところとか、もうちょっといい感じにしてみたいと思ったり。

#!/usr/bin/env perl
use strict;
use warnings;

my @a = (3, 2, 0, 5, 8, 3, 4, 1, 3, 2);
mergesort(@a);

sub mergesort {
    my (@list) = @_;
    return _mergesort(@list);
}

sub _mergesort {
    my (@list) = @_;
    return \@list if @list <= 1;
    my @list2 = splice @list, scalar @list >> 1;
    my @result = merge(_mergesort(@list), _mergesort(@list2));
    return \@result;
}


sub merge {
    my ($list1, $list2) = @_;
    my ($len1, $len2) = (scalar @$list1, scalar @$list2);
    my @result;
    my ($a, $b) = ($list1->[0], $list2->[0]);
    my ($i, $j, $k) = (0, 0, 0);
    while(1){
        if($a <= $b){
            $result[$i] = $a;
            $i += 1; $j += 1;
            last unless $j < $len1;
            $a = $list1->[$j];
        }else{
            $result[$i] = $b;
            $i += 1; $k += 1;
            last unless $k < $len2;
            $b = $list2->[$k];
        }
    }
    while($j < $len1){
        $result[$i] = $list1->[$j];
        $i += 1; $j += 1;
    }
    while($k < $len2){
        $result[$i] = $list2->[$k];
        $i += 1; $k += 1;
    }
    return @result;
}