2014-02-23 45 views
0

我試圖在Perl中實現合併排序,我對Perl很新,我知道我在做數組引用的時候出錯了。完成該過程後,數組最終保持相同的值。請幫忙,因爲我沒有看到我出錯的地方。Perl mergesort - 數組引用

更正後的代碼:

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++; 
     } 
    } 
} 

回答

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]; 

二維數組的引用

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]]; 
print $arr->[0][1]; # identical to $arr->[0]->[1]; 
push @{$arr->[1]}, 5; 
# $arr = [[1, 2], [3, 4, 5]]; 

陣列的2D陣列

...不能存在,因爲陣列只能容納標量

my @arr = ((1, 2), (3, 4)); 
# @arr = (1, 2, 3, 4); 
+0

試過,仍然沒有工作。我已經更新了上面的代碼。 – chettyharish

+0

添加 - >也沒有幫助 – chettyharish

+1

你仍然有'$ auxref [$ i] = $ aref [$ i]'在你的'merge'子文件中。所以這實際上是指你在第4行定義的數組,而不是你在合併子開頭聲明的數組引用。 – aidan

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; 
    } 
} 
+0

另外,這不是我們的失職而是要提到的是,Perl的內置'sort'自5.7。 – aidan

+0

以來一直是合併排序,可以使用'use sort'_mergesort';' – ikegami

+1

Re'進行排序「以下是合併排序的一個版本依賴於所有的引用「,你無需複製整個數組的每一級遞歸,以避免處理引用,這是一件壞事,不是一件好事,你不應該爲此感到驕傲,我的downvote不僅僅是爲了那個,但實際上並沒有幫助OP,他試圖學習,他沒有在尋找一個實現(否則他只是使用內建的'sort')。 – ikegami