我试图在Perl中实现merge-sort,我对Perl很新,我知道我对数组引用做错了。进程完成后,数组最终保持相同的值。请帮助因为我看不出我错在哪里。
更正后的代码:
use strict;
use warnings;
my ( @aref, @auxref ) = ();
my ( $hi, $lo, $i, $j, $k, $n ) = 0;
@aref = ( 5, 7, 6, 3, 4, 1, 8, 9, 4 );
$n = @aref;
mergeSort( \@aref, \@auxref, 0, $n - 1 );
print "@auxref\n";
print "@aref\n";
sub mergeSort {
my ($aref) = $_[0];
my ($auxref) = $_[1];
my $lo = $_[2];
my $hi = $_[3];
if ( $hi <= $lo ) { return; }
my $mid = 0;
$mid = int( $lo + ( $hi - $lo ) / 2 );
mergeSort( $aref, $auxref, $lo, $mid );
mergeSort( $aref, $auxref, $mid + 1, $hi );
merge( $aref, $auxref, $lo, $mid, $hi );
}
sub merge {
my ($aref) = $_[0];
my ($auxref) = $_[1];
my $lo = $_[2];
my $mid = $_[3];
my $hi = $_[4];
for ( $i = $lo ; $i <= $hi ; $i++ ) {
$auxref->[$i] = $aref->[$i];
}
$i = $lo;
$j = $mid + 1;
for ( $k = $lo ; $k <= $hi ; $k++ ) {
if ( $i > $mid ) {
$aref->[$k] = $auxref->[$j];
$j++;
}
elsif ( $j > $hi ) {
$aref->[$k] = $auxref->[$i];
$i++;
}
elsif ( $auxref->[$i] <= $auxref->[$j] ) {
$aref->[$k] = $auxref->[$i];
$i++;
}
else {
$aref->[$k] = $auxref->[$j];
$j++;
}
}
}
答案 0 :(得分:2)
在sub merge
中,您有两个阵列参考:$auxref
和$aref
。
您正在访问数组元素,就像它们是普通数组(即$aref[0]
)一样,但由于它们是数组引用,您需要首先使用箭头取消引用:$aref->[0]
。
将use strict;
和use warnings;
添加到脚本顶部应该已经淘汰了这些错误了吗?
的阵列强> 的
my @arr = (1, 2, 3, 4);
$arr[0] = 5;
push @arr, 6;
# @arr = (5, 2, 3, 4, 6)
数组引用
my $arr = [1,2,3];
$arr->[0] = 5;
push @$arr, 6;
# $arr = [5, 2, 3, 4, 6];
数组引用的2D数组
my @arr = ([1, 2], [3, 4]);
print $arr[0][1]; # identical to $arr[0]->[1];
push @{$arr[1]}, 5;
# @arr = ([1, 2], [3, 4, 5]);
数组引用的2D arrayref
my $arr = [[1, 2], [3, 4]];
print $arr->[0][1]; # identical to $arr->[0]->[1];
push @{$arr->[1]}, 5;
# $arr = [[1, 2], [3, 4, 5]];
二维数组阵列
...不能存在,因为数组只能容纳标量
my @arr = ((1, 2), (3, 4));
# @arr = (1, 2, 3, 4);
答案 1 :(得分:0)
以下是merge sort的版本,完全不依赖于引用。它几乎肯定不像一些原始的合并排序算法那样具有内存效率,但它可以完成工作。
use strict;
use warnings;
my @array = ( 5, 7, 6, 3, 4, 1, 8, 9, 4 );
my @sorted = mergeSort(@array);
print "@sorted\n";
sub mergeSort {
my @array = @_;
if (@array > 1) {
my $mid = int(@array / 2);
my @lowArray = mergeSort(@array[0..$mid-1]);
my @highArray = mergeSort(@array[$mid..$#array]);
# Merge the two halves
my @newArray = ();
while (@lowArray && @highArray) {
if ($lowArray[0] < $highArray[0]) {
push @newArray, shift @lowArray;
} else {
push @newArray, shift @highArray;
}
}
# Either the low or high array will be empty at this point,
# so no need to compare for the remainder.
return (@newArray, @lowArray, @highArray);
} else {
return @array;
}
}