#include <stdio.h>
int Partition (int * A, int p, int r)
{
printf("PARTITION\n");
int x=0;
x=A[r];
int i=p-1, j=r+1;
int temp;
int k=0;
while(1)
{
printf("\tLOOP\n");
do
{
j=j-1;
} while(A[j]>x) ;
do
{
i=i+1;
} while(A[i]<x);
if (i<j)
{
temp=A[i];
A[i]=A[j];
A[j]=temp;
}
else
{
printf ("ARRAY: ");
for (k=p; k<=r; k++)
printf ("%d,",A[k]);
printf ("\nRETURNING : %d \n", j);
return j;
}
}
}
void QuickSort(int * A, int p, int r)
{
int q;
if (p<r)
{
q = Partition (A,p,r);
QuickSort(A,p,q);
QuickSort(A,q+1,r);
}
}
int main()
{
int A[9] = {9,2,4,1,7,8,3,5,6};
int i;
QuickSort(A,0,8);
for (i=0;i<=8;i++)
{
printf("%d ", A[i]);
}
return 0;
}
在 GDB 上一个小时后,我把这个程序的问题缩小到了:
我的数组有从 0-9 的索引。它首先被划分为 0-5 和 6-9。然后 0-5 部分被划分为 0-2 和 3-5 然后 0-2 部分被划分为 0-0 和 1-2 现在 0-0 部分由于if (p<r)
条件而被跳过,但程序调用 Partition (A,1,2) 为另一部分。现在这是程序卡住的地方,它一次又一次地调用 Partition (A,1,2),因为它一直返回 '2' 作为枢轴索引。
为什么会这样?我无法理解程序逻辑上哪里出错了,我遵循了互联网上各个地方给出的确切伪代码。
编辑:我能够通过使用if (i<=j)
而不是if (i<j)
in来解决问题Partition
。它迫使j
再次递减,但这只是因为我很幸运选择do while
了而不是while
. 我仍然不明白为什么直接实现 Quicksort 伪代码不起作用。