2013-03-12 11 views
5

私のJavaの宿題のために、私は再帰的なマージソートクラスを書くのに苦労しています。現在、再帰を開始する3つのメソッド「ドライバ」メソッド、再帰的なmergeSortメソッド、およびmergeメソッドがあります。どのような変数を変更するかによって、出力はすべて0の配列か、元の配列と同じ順番になります。唯一のことは、元のmergeSortメソッドは1つの配列で取る必要があり、mergeメソッドは何も返すことができません。多くの助けを借りて助けてくださいマージソートの問題

import java.util.Arrays; 
public class merge2 { 
    public static void main(String[] args){ 
     int []a={22,45,1,4,89,7,0}; 
     mergeSort(a); 
     System.out.println(Arrays.toString(a));     
    } 

    public static void mergeSort(int [] a){ 
     mergeSort(a,0,a.length-1); 
    } 

    public static void mergeSort(int []a, int beg,int end){ 
     if(beg<end){ 
      int mid=(beg+end)/2; 
      mergeSort(a,beg,mid); 
      mergeSort(a,mid+1,end); 
      merge(a,beg,mid,end); 
     } 
    } 

    private static void merge(int []a, int beg, int middle, int end){ 
     int [] d=new int[a.length]; 
     int mid=middle+1; //start of second half of array 
     for(int i=0;i<d.length;i++){ 
      if(beg<=middle && mid<=end){ 
       if(a[beg]<=a[mid]) { 
       d[i]=a[beg]; 
       beg++; 
       } else if(a[mid]<=a[beg]){ 
         d[i]=a[mid]; 
         mid++; 
       } 
      }else if(beg>middle){ 
       d[i]=a[mid]; 
       mid++; 
      }else if(mid==a.length){ 
       d[i]=a[beg]; 
       beg++; 
      } 
     } 
     for(int w=0;w<d.length;w++){ 
      a[w]=d[w]; 
     } 
    } 
} 
+0

は、あなたは間違って行くように思われる場所を確認するために、デバッガでコードをステップ実行しようとしたことがあり、次の? – millimoose

答えて

1

Okソリューションを修正しました。あなたの主な問題は//<= hereと記されていた。 mid終了インデックスを実行すると、aからdに値が割り当てられていないので、0のままになっていました。この問題を解決するには==>=に置き換えなければなりませんでした。
私はまた、あなたの作品をインデックスで修正しました。あなたは、各レベルでアレイ全体を走らせる必要はありません。また、あなたの複雑さはこのように苦しんでいます。私はその約O(n^2)と思います。 O(nlog(n))の複雑さを保つために、この再帰レベルで処理される配列の一部だけを実行すれば十分です。

固定アルゴリズムは

public static void main(String[] args){ 
    int []a={22,45,1,4,89,7,0}; 
    mergeSort(a); 
    System.out.println(Arrays.toString(a)); 

} 

public static void mergeSort(int [] a){ 
    mergeSort(a,0,a.length-1); 
} 

public static void mergeSort(int []a, int beg,int end){ 
    if(beg<end){ 
     int mid=(beg+end)/2; 
     mergeSort(a,beg,mid); 
     mergeSort(a,mid+1,end); 
     merge(a,beg,mid,end); 
    } 
} 

private static void merge(int []a, int beg, int middle, int end){ 
    int [] d=new int[a.length]; 
    int mid=middle+1; //start of second half of array 
    int beg1=beg; 
    for(int i=beg1;i<=end;i++){ 
     if(beg<=middle && mid<=end){ 
      if(a[beg]<=a[mid]) { 
      d[i]=a[beg]; 
      beg++; 
      } else if(a[mid]<=a[beg]){ 
        d[i]=a[mid]; 
        mid++; 
      } 
     }else if(beg>middle){   
      d[i]=a[mid]; 
      mid++; 
     }else if(mid>=end){ //<= here 
      d[i]=a[beg]; 
      beg++; 
     } 
    } 
    for(int w=beg1;w<=end;w++){ 
     a[w]=d[w]; 
    } 
} 
+0

ありがとうございました。完璧に働いた。私がデバッグモードでこれを実行し始めたら、私はアレイ全体を見渡していたが、どの値が止まるか分からなかったことに気づいた。 – user1943221

+0

私は理由を尋ねることができますか?私は==を使用しました。中間が中間点と等しい場合、配列の半分がソートされ、beg-middleからの値がコピーされなければならないと思ったからです。 – user1943221

+0

'(mid == end)'の配列の上限に達すると、Valuを 'a'から' d'にコピーし、 'mid ++'の中間を増やします(今は 'mid == end + 1')。しかし、下半分が上半分より大きい数であれば、ここで止めることはできません。コピーする必要もあります。 '(mid> = end)の代わりに'(mid == end + 1) 'があれば、もっと正確になるでしょう。 –

3

ここには、mergeSortメソッドの擬似コードがあります。それは新しい配列を作成する代わりに、既存の配列を変更している、あなたのマージ方法として

if (sublist has only one value) 
    do nothing 
else if (sublist has two values) 
    switch if necessary 
else // recursion, divide list into two halves 
    Find midpoint of current sublist 
    Call mergeSort and process left sublist 
    Call mergeSort and process right sublist 
    merge left and right sublists 

:私は、あなたは、1つのまたは2つの要素のためのベースケースを無視していることがわかります。私はそれを実装するためにArrayListを使用することをお勧めします:

private void merge(int[] a, int first, int mid, int last) 
    { 
    ArrayList<Integer> left = new ArrayList<Integer>(mid - first + 1), right = new ArrayList<Integer>(last - mid); 
    for(int m = first; m <= mid; ++m) //initialize left sublist 
    { 
     left.add(a[m]); 
    } 
    for(int m = mid + 1; m <= last; ++m) //initialize right sublist 
    { 
     right.add(a[m]); 
    } 
    int i = first; 
    while(!left.isEmpty() || !right.isEmpty()) //while either list has an element 
    { 
     if(left.isEmpty()) 
     { 
     a[i++] = right.remove(0); 
     } 
     else if(right.isEmpty()) 
     { 
     a[i++] = left.remove(0); 
     } 
     else if (left.get(0) < right.get(0)) 
     { 
     a[i++] = left.remove(0); 
     } 
     else 
     { 
     a[i++] = right.remove(0); 
     } 
    } 
    } 
+0

+1マージソートの実装を掘り下げようとしている人なら誰でも+1できます。 –

+0

ありがとう、私はあなたの擬似コードとマージメソッドで動作するように私のmergeSortメソッドを変更しました。これを実行すると、私はstackoverflowerrorを取得します。私はarraylistを使用することはできませんが、私はそれを変更することができます言及を忘れた – user1943221