2014-10-30 15 views
0

我創建了一個完整的,可運行的示例,它重現了沒有實際按mergesort排序的列表的錯誤。什麼是打印到控制檯22, 22, 22, 1, 1, 1, -2, -2, -2, 1, 22, -2, 1, 22, -2。所以似乎mergesort從不影響列表的後半部分,而前半部分只是因爲insertSort被成功調用而被排序。任何幫助和建議表示讚賞。謝謝!java fork/join mergesort已更新以方便複製

package threadedmergesort; 

import java.util.ArrayList; 
import java.util.Comparator; 
import java.util.concurrent.ForkJoinPool; 
import java.util.concurrent.RecursiveAction; 

public class ThreadedMergeSort implements Comparator<Integer>{ 

    public static void main(String[] args) { 
     ArrayList<Integer> toSort = new ArrayList<Integer>(); 
     toSort.add(1); 
     toSort.add(22); 
     toSort.add(-2); 
     toSort.add(1); 
     toSort.add(22); 
     toSort.add(-2); 
     toSort.add(1); 
     toSort.add(22); 
     toSort.add(-2); 
     toSort.add(1); 
     toSort.add(22); 
     toSort.add(-2); 
     toSort.add(1); 
     toSort.add(22); 
     toSort.add(-2); 
     toSort.add(1); 
     toSort.add(22); 
     toSort.add(-2); 

     ThreadedMergeSort.sort(toSort, 0, toSort.size()-11); 
     for (Integer e: toSort){ 
       System.out.println(e); 
       } 
    } 

    public static void sort (ArrayList<Integer> inputComp){ 
     sort(inputComp, 0, inputComp.size()-1); 
    } 
    public static void sort (ArrayList<Integer> inputComp, int low, int high){ 
     if (high-low< SIZE_LIMIT){ 
      insertionSort(inputComp, low, high); 
      return; 
     } 
     ArrayList<Integer> temp = new ArrayList(inputComp.size()); 
     pool.invoke(new SortTask(inputComp, temp, low, high)); 
     System.out.println("pool.invoke"); 
    } 

    static class SortTask extends RecursiveAction{ 
     ArrayList<Integer> inputComp; 
     ArrayList<Integer> temp; 
     int low; 
     int high; 

     public SortTask(ArrayList<Integer> inputComp, ArrayList<Integer> temp, int low, int high){ 
      this.inputComp=inputComp; 
      this.temp=temp; 
      this.low=low; 
      this.high=high; 
     } 

     @Override 
     protected void compute(){ 
      if (high-low<SIZE_LIMIT){ 
       insertionSort(inputComp, low, high); 
       return; 
      } 
      int middle = (low + high)/2; 
      invokeAll(new SortTask(inputComp, temp, low, middle), new SortTask(inputComp, temp, middle+1, high)); 
      merge(inputComp, temp, low, middle, high); 
     } 
    } 
     @Override 
     public int compare(Integer c1, Integer c2){ 
     if (c1> c2){ 
      return -1; 
     } 
     if (c1 > c2){ 
      return 1; 
     } 
     return 0; 
    } 

    public static void arrayListCopy(ArrayList<Integer> src, int srcPos, ArrayList<Integer> dest, int destPos, int length){ 
     for (int i = 0; i< length; i++){ 
      dest.set(destPos+i, src.get(srcPos+i)); 
     } 
    } 
    private static void merge(ArrayList<Integer> inputComp1, ArrayList<Integer> inputComp2, int low, int middle, int high){ 
     ThreadedMergeSort sort = new ThreadedMergeSort(); 
     if(sort.compare(inputComp1.get(middle), inputComp1.get(middle+1)) <0){ 
      return; 
     } 
     arrayListCopy(inputComp1, low, inputComp2, low, middle-low+1); 
     int i = low; 
     int j = middle+1; 
     int k = low; 
     while(k < j && j <= high){ 
      if(sort.compare(inputComp2.get(i),inputComp1.get(j)) <= 0){ 
       inputComp1.set(k++, inputComp2.get(i++)); 
      } 
      else{ 
       inputComp1.set(k++,inputComp1.get(j++)); 
      } 
     } 
     arrayListCopy(inputComp2, i, inputComp1, k, j-k); 
    } 

    private static void insertionSort(ArrayList<Integer> inputComp, int low, int high){ 
     ThreadedMergeSort sort = new ThreadedMergeSort(); 
     for(int i = low+1; i<=high; i++){ 
      int j = i; 
      Integer entry = inputComp.get(j); 
      while(low<j && sort.compare(entry, inputComp.get(j-1))< 0){ 
       inputComp.set(j,inputComp.get(j-1)); 
       --j; 
      } 
      inputComp.set(j,entry); 
     } 
    } 
    private static final ForkJoinPool pool = new ForkJoinPool(); 
    private static final int SIZE_LIMIT = 8; 
} 
+0

您是否需要實現自己的排序方法? Arrays.sort和Arrays.parallelSort通常是最好的解決方案。 – Mac70 2014-10-30 00:20:16

+0

我正在使用ArrayList,所以我不能使用Array.sort。我需要一個ArrayList,所以我可以動態地添加新條目,但感謝您的建議 – 2014-10-30 00:24:28

+0

在這種情況下,您可以使用Collections.sort或將列表轉換爲數組,將其排序並從已排序的數組中創建新列表。 – Mac70 2014-10-30 00:29:47

回答

0

它在做什麼你問:

ThreadedMergeSort.sort(toSort, 0, toSort.size()-11); 

您的意思是1還是11?

+0

我補充說,因爲如果大小比SIZE_LIMIT大,它會返回一個IndexOutOfBoundsException。這可能是我的代碼的真正問題。您可以通過刪除11或將其更改爲1來重現此操作。前者將返回「由:java.lang.IndexOutOfBoundsException:Index:15,Size:15引起的」,而後者將返回相同的索引和大小0. – 2014-10-30 00:42:33

+0

你會得到哪些索引超出界限的錯誤? – CharlieS 2014-10-30 00:46:30

+0

爲什麼SIZE_LIMIT設置爲8? – CharlieS 2014-10-30 00:49:39