2012-08-22 25 views
2

一個簡單的快速排序實現我檢討算法的東西,停留在簡單的快速排序算法的實現在java中滯留在隨機轉動

import java.util.Arrays; 
import java.util.Random; 

public class QuickSort { 
    int arr[]; 
    boolean randomPick; 
    Random rand = null; 

    public QuickSort(int[] inputArray) { 
     arr = inputArray; 
     randomPick = false; 
    } 

    public QuickSort(int[] inputArray, boolean random) { 
     arr = inputArray; 
     if (random) { 
      randomPick = true; 
      rand = new Random(System.currentTimeMillis()); 
     } 
     else { 
      randomPick = false; 
     } 
    } 

    public int[] sort() { 
     int start = 0; 
     int end = arr.length - 1; 
     try { 
      _sort(start, end); 
     } 
     catch (StackOverflowError e) { 
      System.out.println("StackOverflow: " + Arrays.toString(arr)); 
     } 
     return arr; 
    } 

    private void _sort(int start, int end) { 
     int i = start; 
     int j = end; 
     int pivotLoc; 
     if (!randomPick) { 
      pivotLoc = (j + i)/2; 
     } 
     else { 
      pivotLoc = rand.nextInt(j - i) + i; 
     } 
     int pivot = arr[pivotLoc]; 
     while (i < j) { // swapping numbers around the pivot 
      while (arr[i] < pivot) { 
       i++; 
      } 
      while (arr[j] > pivot) { 
       j--; 
      } 
      if (i < j) { 
       int t = arr[i]; 
       arr[i] = arr[j]; 
       arr[j] = t; 
       i++; 
       j--; 
      } 
     } 
     if (i - start > 1) { 
      _sort(start, i); 
     } 
     if (end - i > 1) { 
      _sort(i, end); 
     } 
    } 
} 

的代碼都可以選擇中間的數字爲支點或隨機選擇一個數字作爲數據透視表,並通過循環調用_sort對數組進行排序。它在第一種情況下工作,但在第二種情況下失敗。

的情況是:當它到達一個子陣列,因爲這{3,5,5},我==啓動== 0和j ==端== 2。最後5和5交換,我變成2,j變成1(i ++和j--)。然後,因爲i - start>1它會一遍又一遍地調用_sort並最終喚起stackoverflow錯誤。然而,錯誤應該發生在第一種情況下(固定樞軸),至今尚未發生......

我不知道我的代碼有什麼問題。我知道閱讀其他人編寫的代碼並不是一種樂趣,但有任何幫助?

回答

1

你犯了個小錯誤在你的遞歸條件下,無論是startend比較反對i,則start應當針對j

您有:

if (i - start > 1) { 
     _sort(start, i); 
    } 
    if (end - i > 1) { 
     _sort(i, end); 
    } 

需要是:

if (j > start) { 
     _sort(start, j); 
    } 
    if (end > i) { 
     _sort(i, end); 
    } 

而你的ij比較需要允許等於:

// here ----v 
     if (i <= j) { 
      int t = arr[i]; 
      arr[i] = arr[j]; 
      arr[j] = t; 
      i++; 
      j--; 
     } 
+0

運行良好(是的,你只是提醒我,殲實際上應該是上限左子問題,而不是我的),但請您讓我問一個問題:什麼是使用i <= j?我想如果我== j然後他們都指向相同的元素,這將是浪費交換。但是,當我刪除該平等的堆棧再次溢出。唯一重要的事情就是i ++和j--但是我只是看不到什麼會消耗掉堆棧。必須是一個愚蠢的問題,但請幫助謝謝。 – NSF

+0

@NSF什麼是堆棧是因爲我和j從來沒有碰過或越過對方,並且因爲你繼續運行'_sort(start,i);'而不是'_sort(start,j);',2 - 0總是> 1,因此遞歸循環。 –

+0

不,我的意思是如果你的「我<= j」和我的「我 NSF