新手程序员在这里尝试实施快速排序,但它不起作用。我查看了在线资源,但我似乎无法在我的实现中发现错误。提前谢谢。
编辑问题我似乎已经陷入快速排序功能,程序就会挂起。当我尝试使用printf进行调试时,原始数组似乎已使用意外数字(而不是原始列表)进行了修改,例如0。
void quicksort(int a[], const int start, const int end)
{
if( (end - start + 1 ) < 2)
return;
int pivot = a[rand()%(end - start)];
//Two pointers
int L = start;
int R = end;
while(L < R)
{
while(a[L] < pivot)
L++;
while(a[R] > pivot)
R--;
if(L < R)
swap(a,L,R);
}
quicksort(a, start, L-1);
quicksort(a, L+1, end );
}
void swap(int a[], const int pos1, const int pos2)
{
a[pos1] ^= a[pos2];
a[pos2] ^= a[pos1];
a[pos1] ^= a[pos2];
}
int main()
{
int array[20] = {0};
int size = sizeof(array)/sizeof(array[0]);//index range = size - 1
int i = 0;
printf("Original: ");
for (i; i < size; i++)
{
array[i] = rand()%100+ 1;
printf("%d ", array[i]);
}
printf("\n");
quicksort(array,0,size-1);
int j = 0;
printf("Sorted: ");
for(j; j < size; j++)
printf("%d ", array[j]);
printf("\n");
}
附加问题:关于递归调用quicksort,左右指针是否总是指向每个分区末尾的枢轴?如果是这样,从开始调用快速排序到L-1和L + 1结束是否正确?
此外,交换前的if(L&lt; R)是否必要?
答案 0 :(得分:2)
我认为问题源于逻辑中的两个错误。第一个是:
int pivot = a[rand()%(end - start)];
请注意,这总是选择[0,end - start]范围内的一个数据透视而不是[start,end]。我想你想要像
这样的东西int pivot = a[rand()%(end - start) + start];
这样您就可以选择所需范围内的数据透视。
另一个错误出现在这个循环代码中:
while(L < R)
{
while(a[L] < pivot)
L++;
while(a[R] > pivot)
R--;
if(L < R)
swap(a,L,R);
}
假设L < R
,a[L]
,a[R]
和pivot
都是相同的值。例如,如果您快速分配包含重复元素的范围,则可能会出现这种情况。当rand
与rand
的标准Linux实现一起使用时,它也出现了(我在我的机器上尝试了这个,27次重复了两次)。如果是这种情况,那么您永远不会移动L或R,因为循环中的条件总是评估为false。当需要重复时,您需要更新逻辑以分区元素,否则您将在此处进入无限循环。
希望这有帮助!
答案 1 :(得分:0)
在While语句之后,R应该小于L,试试这个:
quicksort(a, start, R);
quicksort(a, L, end );
并且声明if(L < R)
不是必需的。