2017-08-31 95 views
0

我正在嘗試執行快速排序使用分而治之技術。我得到的遞歸一個堆棧溢出錯誤調用。這裏是我的代碼:快速排序分而治之

public static void main(String[] args) { 
    ArrayList<Integer> unsorted = new ArrayList<Integer>(); 

    unsorted.add(23); 
    unsorted.add(5); 
    unsorted.add(1); 
    unsorted.add(-8); 
    unsorted.add(101); 
    unsorted.add(21); 
    unsorted.add(10); 
    unsorted.add(10); 
    unsorted.add(0); 
    unsorted.add(50); 

    ArrayList<Integer> sorted = Quicksort(unsorted); 
    System.out.println(sorted.toString()); 
} 

public static ArrayList<Integer> Quicksort(ArrayList<Integer> unsorted) { 

    if (unsorted.size() <= 1) 
     return unsorted; 

    ArrayList<Integer> less = new ArrayList<Integer>(); 
    ArrayList<Integer> more = new ArrayList<Integer>(); 

    int pivotindex = unsorted.size()/2; 

    for (int i = 0; i < unsorted.size(); i++) { 
     if (unsorted.get(i) < unsorted.get(pivotindex)) 
      less.add(unsorted.get(i)); 
     else 
      more.add(unsorted.get(i)); 
    } 

    ArrayList<Integer> sorted = Quicksort(less); 
    sorted.add(unsorted.get(pivotindex)); 
    sorted.addAll(Quicksort(more)); 

    return sorted; 
} 

我希望它使用ArrayLists來實現。任何人都可以指出我錯在哪裏?

非常感謝。

+0

就這樣,任何等於主軸(包括主軸本身)的值都被添加到'more'列表中。 – litelite

+2

錯誤似乎在於你在方法的每次運行中添加'pivotindex'的副本。當你迭代未排序時,不檢查該值是否等於pivotindex,因此它被添加到'more'數組列表中。然後你在'sorted.add(unsorted.get(pivotindex))'處再次添加它,所以數組永遠長大,這會導致你的stackoverflow錯誤。 – gimg1

+0

在for循環中,您要比較樞軸索引處的元素與其自身,並最終將其添加到排序列表中作爲更少或更多節,AND作爲樞軸索引處的元素。爲此,在每次遞歸調用,您都加大了列表的大小,並調用永遠不會結束 –

回答

5

你應該保持從moreless列出一個單獨的地方你pivot值。

更改條件:

else if(unsorted.get(i) > unsorted.get(pivotindex)) 
     more.add(unsorted.get(i));  

它應該工作的罰款。希望這可以幫助。

編輯:正如在喬希的評論中提到的,如果有多個元素具有與主元相同的值,這將不起作用。對於這一點,你所能做的就是定義一個名爲equal另一個ArrayList和加入這一行:

else 
    equal.add(unsorted.get(i)); 

然後,當你合併陣列後面這份名單與pivot元素一起追加。

感謝您指出了這一點。 :)

注:這種類型將不被保證是穩定(作爲具有可能不按照原來的陣列中的它們的相對位置被放置相同的值的元素)。

+0

如果有多個與pivot元素具有相同值的元素,這仍然可以工作嗎?這些元素將會使用這種方法丟失,因爲您不會將它們添加到排序列表中。看到我的答案在下面,我堅持他們,並將它們添加到排序列表。 –

+0

我想這個問題聰明的解決辦法是定義另一個名爲'equal'的數組列表,然後在將數組連接到數組時將它與數據透視表一起放置。 –

2

這似乎是可以很容易地

ArrayList<Integer> less = new ArrayList<Integer>(); 
ArrayList<Integer> equal = new ArrayList<Integer>(); 
ArrayList<Integer> more = new ArrayList<Integer>(); 

int pivotindex = unsorted.size()/2; 

for (int i = 0; i < unsorted.size(); i++) { 
    if (unsorted.get(i) < unsorted.get(pivotindex)) //Put whatever is less to the left 
     less.add(unsorted.get(i)); 
    else if (unsorted.get(i) == unsorted.get(pivotindex)) //Put whatever is equal in the middle 
     equal.add(unsorted.get(i)); 
    else //Put everything else to the right (everything greater) 
     more.add(unsorted.get(i)); 
} 

ArrayList<Integer> sorted = Quicksort(less); //Sort the left, then add 
sorted.addAll(equal); //Middle is already sorted (all equal), add 
sorted.addAll(Quicksort(more)); //Sort the right, then add 

return sorted; 
0

以下作品完美地可以理解的解決方案。

public static void main(String[] args) { 
     ArrayList<Integer> unsorted = new ArrayList<Integer>(); 

      unsorted.add(23); 
      unsorted.add(5); 
      unsorted.add(1); 
      unsorted.add(-8); 
      unsorted.add(101); 
      unsorted.add(21); 
      unsorted.add(10); 
      unsorted.add(10); 
      unsorted.add(0); 
      unsorted.add(50); 

      ArrayList<Integer> sorted = Quicksort(unsorted); 
      System.out.println(sorted.toString()); 
     } 

     public static ArrayList<Integer> Quicksort(ArrayList<Integer> unsorted) { 
       System.out.println(unsorted.size()); 
      if (unsorted.size() <= 1) 
       return unsorted; 

      ArrayList<Integer> less = new ArrayList<Integer>(); 
      ArrayList<Integer> more = new ArrayList<Integer>(); 

      int pivotindex = unsorted.size()/2; 

      for (int i = 0; i < unsorted.size(); i++) { 
       if (unsorted.get(i) < unsorted.get(pivotindex)) 
        less.add(unsorted.get(i)); 
       else 
        more.add(unsorted.get(i)); 
      } 
      if(less.isEmpty()) { 
       less.add(more.remove(more.size() - 1)); 
      } 

      ArrayList<Integer> sorted = Quicksort(less); 
      //sorted.add(unsorted.get(pivotindex)); 
      sorted.addAll(Quicksort(more)); 

      return sorted; 
     }