繁体   English   中英

快速选择算法的实现以找到第k个最小的数字

[英]Implementation of the quick select algorithm to find kth smallest number

我目前正在开发一个程序,使用快速选择算法查找数组的第 k 个最小数字。 我已经完成了它并且它可以工作,但每次都没有给出正确的结果。

这是我的代码(我没有包括我的partitionswap算法,我很确定它们是正确的):

/*
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);
    }
}

一切都编译得很好。 然后我尝试在以下数组上使用该程序: [1,3,8,2,4,9,7]

这些是我的结果:

> kthsm 2
4
> kthsm 1
1
> kthsm 3
2

如您所见,它在第 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;
}

在您的分区函数中,循环条件应该是x < right ,而不是x < right - 1

此外,在 quickselect 的 if 语句中,您应该将p-1两种用法都切换为p p已经是一个索引,通过将k减 1,你也可以将它变成一个索引(而不是一个订单)。 无需再次将p减 1。

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);
    }
}

这是一个工作示例。 http://ideone.com/Bkaglb

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM