在写这篇文章之前,我试图找到一个用C语言实现的算法的例子,但是在google上搜索一段时间之后找不到一个。虽然我有可能在编程方面不够精通,无法正确搜索它。这段代码基于关于算法的文章(Java中的示例)和我发现的另一种Java实现。
它目前陷入无限循环,但我找不到原因。部分原因可能是因为我试图将代码转换为C但是犯了错误。
#include <stdio.h>
void printArray(int A[], int size) {
printf("[ ");
int i = 0;
for (i = 0; i < size; i++) {
printf("%d", A[i]);
if (i < size - 1) printf(", ");
}
printf(" ]\n");
}
void quickSort(int A[], int left, int right) {
if (right <= left ) return;
int temp;
if (A[right] < A[left]) {
temp = A[right];
A[right] = A[left];
A[left] = temp;
}
int pLow = left + 1;
int pHigh = right - 1;
int i = left + 1;
while (i <= pHigh) {
if (A[i] < A[pLow]) {
temp = A[i];
A[i] = A[pLow];
A[pLow] = temp;
A[pLow++];
i++;
}
else if (A[pHigh] < A[i]) {
temp = A[i];
A[i] = A[pHigh];
A[pHigh] = temp;
A[pHigh--];
}
else i++;
}
temp = A[left];
A[left] = A[--pLow];
A[pLow] = temp;
temp = A[right];
A[right] = A[++pHigh];
A[pHigh] = temp;
quickSort(A, left, pLow-1);
if (A[pLow] < A[pHigh]) quickSort(A, pLow+1, pHigh-1);
quickSort(A, pHigh+1, right);
}
int main() {
int size = 10;
int array[10] = {1, 0, 7, 9, 6, 2, 5, 8, 4, 3};
printf("Before: ");
printArray(array, size);
quickSort(array, 0, size-1);
printf("After: ");
printArray(array, size);
}
答案 0 :(得分:0)
这很可疑......
int pLow = left + 1;
int pHigh = right - 1;
...当您遇到麻烦时确保A[left] < A[right]
,但没有做任何事情来测试或修正A[left + 1]
和A[right - 1]
的相对顺序。我想你想从子阵列的最末端选择枢轴:
int pLow = left;
int pHigh = right;
但更重要的是,您的递归没有终止条件。 quickSort()
时,right <= left
函数应该终止而不做任何事情(特别是没有递归)。
<强>更新强>
虽然我不会像我自己那样实现它,但以下代表了我可以想出的将起始代码转换为工作类的最小变化:
void quickSort(int A[], int left, int right) {
int temp;
if (right <= left) return;
if (A[right] < A[left]) {
temp = A[right];
A[right] = A[left];
A[left] = temp;
}
/* A[left] and A[right] are the left and right pivot values */
int pLow = left + 1;
int pHigh = right - 1;
int i = left + 1;
while (i <= pHigh) {
if (A[i] < A[left]) {
temp = A[i];
A[i++] = A[pLow];
A[pLow++] = temp;
}
else if (A[right] < A[i]) {
temp = A[i];
A[i] = A[pHigh]; /* i not incremented here */
A[pHigh--] = temp;
}
else i++;
}
temp = A[left];
A[left] = A[--pLow];
A[pLow] = temp;
temp = A[right];
A[right] = A[++pHigh];
A[pHigh] = temp;
quickSort(A, left, pLow - 1);
if (A[pLow] < A[pHigh]) quickSort(A, pLow + 1, pHigh - 1);
quickSort(A, pHigh + 1, right);
}
请特别注意,只有在A[left]
和A[right]
之前维持枢轴值时,循环结束后的两次交换才有意义。但是,这意味着内循环中的比较必须与那些值相对应,而不是A[pLow]
和A[pHigh]
。
我保留了pLow
和pHigh
的原始初始化(我之前的评论不符合规定);因此,这些代表低和高分区中下一个可用位置的索引。我也改变了一些增量和减量。