利用快速排序算法的思想,在一组随机排序数中,查找第K小的值。

本文介绍了基于快速排序思想的两种算法,用于在一组随机排列的数中查找第k小的数。讨论了算法实现细节及潜在的bug,并通过实例展示了应用过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/*****************************************
    在一组随机排列的数中找出第k小的值
******************************************/

#include <stdio.h>
#include <assert.h>

void TraversalArray(const int array[], int len)
{
    assert(array != NULL);
    assert(len > 0);

    unsigned int index = 0;

    for(index = 0; index < len; index++)
    {
        printf("%3d", array[index]);
    }

    printf("\n");
}

/************************************************************************************
int partition(int array[], int left, int right)
{
    assert(array != NULL);

    int pivot = array[left];

    while(left < right)
    {
        while((array[right] >= pivot) && (left < right))
        {
            right--;
        }
        array[left] = array[right];

        while((array[left] <= pivot) && (left < right))
        {
            left++;
        }
        array[right] = array[left];
    }

    array[left] = pivot;

    return left;
}
*************************************************************************************/

int partition(int array[], int low, int high)
{
    assert(array != NULL);

    int pivot = array[low];/*partition()函数将序列分开,以array[low]为轴心,前小后大*/
    int left = low;
    int right = high;
    int tempValue;

    while(left < right)
    {
        while((array[right] >= pivot) && (left < right))
        {
            right--;
        }

        while((array[left] <= pivot) && (left < right))
        {
            left++;
        }

        if(left < right)/*以array[low]为轴心,把后面小于pivot的数与前面大于pivot的数互换*/
        {
            tempValue = array[left];
            array[left] = array[right];
            array[right] = tempValue;
        }
    }

    array[low] = array[right];
    array[right] = pivot;

    return right;
}

/*利用快速排序的思想,从low到high之间找到第K小的值*/
int Order_Statistic(int array[], int low, int high, int key)
{
    int pivot = partition(array, low, high);/*返回值为第pivot小的值,即array[pivot]*/
    if(pivot == key)
    {
        return pivot;/*成功返回找到的元素位置*/
    }
    else if(pivot < key)
    {
        Order_Statistic(array, pivot+1, high, key);/*递归在后面部分查找*/
    }
    else
    {
        Order_Statistic(array, low, pivot-1, key);/*递归在前面小的部分继续查找*/
    }
}

int main(void)
{
    int array[] = {9, 0, 1, 2, 8, 7, 5, 4, 6, 3};

    TraversalArray(array, sizeof(array)/sizeof(array[0]));

    int index = Order_Statistic(array, 0, sizeof(array)/sizeof(array[0])-1, 4);    
    printf("The number is %d \n", array[index-1]);
    
    TraversalArray(array, sizeof(array)/sizeof(array[0]));
    
    return    0;
}

/********************************************************************************
这两个快速查找算法都是基于快速排序思想得到的。但有个bug就是,查找第K小的值时,
如果这个K值大于一半时(也就是这个值的大小在所有随机数中大于一半的数时)
得到的答案是不对的。
*********************************************************************************/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值