2016-09-05 3 views
0

静的リスト(ArrayLists)のマージソートを実装しようとしています。 TopDownとBottomUpの両方の実装があります。しかし、私は抽象マージソートが機能していないと信じています。これは、同じ順序のないリストを持つ両方の実装をテストしたために、マージメソッドが機能していないと思うためです。私は間違いを見つけることができません。プライベートメソッドは異なるクラスにあります。読みやすくするために一緒に置いています。ここにコードがあります。前もって感謝します。マージソートリストの実装TopDown + BottomUp + Abstract MergeSort

public <T> void merge(@NotNull Comparator<T> comparator, @NotNull List<T> list, int lo, int mid, int hi) { 
//  // Merge a[lo..mid] with a[mid+1..hi]. 
     List<T> aux = new ArrayList<>(list);// Copy a[lo..hi] to aux[lo..hi]. 
     int i = lo, j = mid + 1; 
     for (int k = lo; k <= hi; k++) // Merge back to a[lo..hi]. 
      if (i > mid) 
       list.set(k, aux.get(j++)); 
      else if (j > hi) 
       list.set(k, aux.get(i++)); 
      else if (comparator.compare(list.get(i), list.get(j)) > 0) 
       list.set(k, aux.get(j++)); 
      else 
       list.set(k, aux.get(i++)); 
    } 


    public <T> void sort(@NotNull Comparator<T> comparator, @NotNull List<T> list) { 
     sort(comparator, list, 0, list.size() - 1); 
    } 



    //TopDown 
    private <T> void sort(@NotNull Comparator<T> comparator, @NotNull List<T> list, int lo, int hi) { // Sort a[lo..hi]. 
     if (hi <= lo) return; 
     int mid = lo + (hi - lo)/2; 
     sort(comparator, list, lo, mid);  // Sort left half. 
     sort(comparator, list, mid+1, hi);  // Sort right half. 
     merge(comparator, list, lo, mid, hi); // Merge results 
    } 

    //BottomUp 
    private <T> void sort(@NotNull Comparator<T> comparator, @NotNull List<T> list) { 
     for (int mid = 1; mid < list.size(); mid = mid + mid) 
      // mid: subarray size 
      for (int lo = 0; lo < list.size() - mid; lo += mid + mid) { // lo: subarray index 
       merge(comparator, list, lo, lo + mid - 1, Math.min(lo + mid + mid - 1, list.size() - 1)); 
      } 
    } 
+0

抽象マージソートとは何ですか? – rcgldr

+0

両方のマージソーターにメソッド "マージ"が使用されていますか? –

+0

トップダウンとボトムアップの両方が同じマージ機能を使用できます。ボトムアップコールでは、左半分のコピーがあるかどうかを確認する必要があります:merge(...、min(lo + mid -1、list.size()-1)、...)。最上位レベルのソート関数でauxの1回分の割り当てを行い、それをパラメータとしてトップダウンまたはボトムアップソートに渡す方が良いでしょう。現在のコードは、各マージ操作でリストのコピー全体を割り当てています。これは遅くなり、大きなリストでスペースを使い果たす可能性があります。 – rcgldr

答えて

1

merge()のコードは、入力リスト要素(aux)ではなく出力リスト要素(リスト)を比較しています。

 else if (comparator.compare(aux.get(i), aux.get(j)) > 0) 

変更

 else if (comparator.compare(list.get(i), list.get(j)) > 0) 

(マージ理由がある)は、プライベートではなく、そのマージ()とソート()は静的ではありませんか?