在quicksort java中的无限循环

时间:2014-07-24 09:14:20

标签: java algorithm quicksort

我尝试实现一个快速排序算法,但是当我运行我的代码时,它给了我一个无限循环,我不明白,我在代码中的分区方法中犯了错误:

public static int partition(int[] a, int p, int r)
{
    int x = a[p];
    int i = p;
    int j = r + 1;
    while(true)
    {
        while(a[i] < x) 
        {
            i++;
            if (i == r) break;
        }
        while(x > a[j]) 
        {
            j--;
            if (j == p) break;
        }
        if (i >= j) break;

        int tmp = a[i];
        a[i] = a[j];
        tmp = a[i];
    }

    int exch = a[p];
    a[p] = a[j];
    exch = a[p];

    return j;
}

此代码的输入数据:

private static int[] array;
private static Scanner sc = new Scanner(System.in);
public static void main(String[] args){
    int n, m;
    n = sc.nextInt();
    array = new int[n+1];
    int i,j;
    for (i = 0; i != array.length-1; i++)
        array[i] = sc.nextInt();


    for (j = 0; j !=array.length-1; i++)
        System.out.print(array[j]);
    quickSort(array,0,array.length);

}

3 个答案:

答案 0 :(得分:3)

尝试

a[j] = exch;

而不是

exch = a[p];

和相同的错误 - 感谢@Namer和@Zhuinden - 在您的代码中:

int tmp = a[i];
a[i] = a[j];
tmp = a[i];

感谢@DeepanshuBedi,Quicksort in Java - Tutorial描述了算法。它有

i++;
j--;
循环交换后

此外,该函数应该是递归的:

if (low < j)
  quicksort(low, j);
if (i < high)
  quicksort(i, high); 

而不是你的第二次交换。

我建议您复制该页面中的代码 - 您的代码并不像我那样快速。

答案 1 :(得分:1)

您正在实施Cormen Algorithms version of the Quicksort algorithm。 他的版本是这样的(没有提到版权信息,这可以通过简单的谷歌搜索找到):

enter image description here

你的版本几乎全部错过了。例如,在前两行:

int x = a[p]; //Should be a[r]
int i = p; //Should be p-1

再次检查算法的每一步,并且只有在您真正了解算法如何重试以编写正确的函数之后。

此外,您的快速排序功能应该是递归的,我希望您知道what it means

提示:有2个函数,一个是递归的(quickSort),另一个只有一个for循环(partition)。


编辑:我从书中选择了错误的快速排序算法,对不起。正确的一个,你正在使用的那个,如下:

enter image description here

您仍在使用一些非常基本的错误来实现它。以下是最明显的:

  • 您正在使用while循环而不是do-until (do-while in Java)循环,very different

  • 你正在混合两种算法,交换(错误地作为我的第一次 评论指出)在Hoare-Partition中的两倍值 只做一次。

  • 您不需要if (i >= j) break;if (i == r) break; 循环结束条件因为,对于算法的构造,它们 永远不会发生(如果你使用a[i] < x作为破坏条件 或a[i] >= x作为许可条件)。这表明你没有 完全理解算法的工作原理。

  • int i = p; //Should be p-1仍然是错误的。

再次,检查算法的每一步并纠正它,你就在路上! :)

更新:我已经尝试了上面的更正的Hoare分区和每次交换后输入int[] a = {13,19,9,5,12,8,7,4,11,2,6,21};的输出(顺便说一下这是(a)的答案)书中的问题):

[6, 19, 9, 5, 12, 8, 7, 4, 11, 2, 13, 21]
[6, 13, 9, 5, 12, 8, 7, 4, 11, 2, 19, 21]
[6, 2, 9, 5, 12, 8, 7, 4, 11, 13, 19, 21]
[4, 2, 9, 5, 12, 8, 7, 6, 11, 13, 19, 21]
[4, 2, 6, 5, 12, 8, 7, 9, 11, 13, 19, 21]
[4, 2, 5, 6, 12, 8, 7, 9, 11, 13, 19, 21]
[2, 4, 5, 6, 12, 8, 7, 9, 11, 13, 19, 21]
[2, 4, 5, 6, 11, 8, 7, 9, 12, 13, 19, 21]
[2, 4, 5, 6, 9, 8, 7, 11, 12, 13, 19, 21]
[2, 4, 5, 6, 7, 8, 9, 11, 12, 13, 19, 21]

这仅仅是为了检查算法是否有效(可能是打印错误可能导致无限循环)。

答案 2 :(得分:-1)

The basics of quick sort             试试这可能会解决你的问题。

              if (i <= j) {
              tmp = a[i];
              a[i] = a[j];
              a[j] = tmp;
              i++;
              j--;}


           **int exch = a[p];
            a[p] = a[j];
            a[p] = exch;**

编辑了您的代码。    我建议你使用for-loop。

 public static int partition(int[] a, int p, int r)
    {
        int x = a[p];
        int i = p;
        int j = r + 1;
        while(true)
        {
            while(a[i] < x) 
            {
                i++;
                if (i == r) break;
            }
            while(x > a[j]) 
            {
                j--;
                if (j == p) break;
            }
     if (i <= j) {
          tmp = a[i];
          a[i] = a[j];
          a[j] = tmp;
          i++;
          j--;}

        **int exch = a[p];
        a[p] = a[j];
        a[p] = exch;**

        return j;
    }