2012-08-22 24 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