Jav*_*ser 3 c algorithm recursion
我目前正在开发一个程序,使用快速选择算法查找数组的第 k 个最小数字。我已经完成了它并且它可以工作,但每次都没有给出正确的结果。
这是我的代码(我没有包括我的partition或swap算法,我很确定它们是正确的):
/*
inputs...
*A: pointer to array
n: size of array
k: the item in question
*/
int ksmallest(int *A, int n, int k){
int left = 0;
int right = n - 1;
int next = 1;
return quickselect(A, left, right, k);
}
int quickselect(int *A, int left, int right, int k){
//p is position of pivot in the partitioned array
int p = partition(A, left, right);
//k equals pivot got lucky
if (p - 1 == k - 1){
return A[p];
}
//k less than pivot
else if (k - 1 < p - 1){
return quickselect(A, left, p - 1, k);
}
//k greater than pivot
else{
return quickselect(A, p + 1, right, k);
}
}
Run Code Online (Sandbox Code Playgroud)
一切都编译得很好。然后我尝试在以下数组上使用该程序:[1,3,8,2,4,9,7]
这些是我的结果:
> kthsm 2
4
> kthsm 1
1
> kthsm 3
2
Run Code Online (Sandbox Code Playgroud)
如您所见,它在第 1 个最小的项目上正常工作,但在其他项目上却失败了。可能是什么问题呢?我猜我的索引已关闭,但我不确定。
编辑:根据要求在下面添加我的分区和交换代码:
int partition(int *A, int left, int right){
int pivot = A[right], i = left, x;
for (x = left; x < right - 1; x++){
if (A[x] <= pivot){
swap(&A[i], &A[x]);
i++;
}
}
swap(&A[i], &A[right]);
return i;
}
//Swaps
void swap(int *a, int *b){
int temp = *a;
*a = *b;
*b = temp;
}
Run Code Online (Sandbox Code Playgroud)
在您的分区函数中,循环条件应该是x < right,而不是x < right - 1。
此外,在 quickselect 的 if 语句中,您应该将两种用法都切换为p-1to p。p已经是一个索引,通过减少k1 也可以将它变成一个索引(而不是一个订单)。没有必要再减p一。
int partition(int *A, int left, int right){
int pivot = A[right], i = left, x;
for (x = left; x < right; x++){
if (A[x] < pivot){
swap(&A[i], &A[x]);
i++;
}
}
swap(&A[i], &A[right]);
return i;
}
int quickselect(int *A, int left, int right, int k){
//p is position of pivot in the partitioned array
int p = partition(A, left, right);
//k equals pivot got lucky
if (p == k-1){
return A[p];
}
//k less than pivot
else if (k - 1 < p){
return quickselect(A, left, p - 1, k);
}
//k greater than pivot
else{
return quickselect(A, p + 1, right, k);
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个工作示例。http://ideone.com/Bkaglb
| 归档时间: |
|
| 查看次数: |
6909 次 |
| 最近记录: |