线性时间选择

本文深入探讨了快速选择算法,一种用于查找线性序集中第k小元素的有效方法。通过随机化快排实现,平均性能优秀,同时介绍了另一种最坏情况下时间复杂度为O(n)的算法。

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

Description

给定线性序集中n个元素和一个整数k,1 ≤ k ≤ n,请找出这n个元素中第k小的元素

快速选择的变种。

当position = k 时,array[position]为第k小。

当position < k 时, 第k小在右半部分,即 [position+1,right]。

当position > k 时, 第k小在左半部分,即[left,position-1]。

使用随机化快排,最坏时间复杂度为\Omega(n^2),但平均性能很好。

代码如下。

#include <stdio.h>
#include <math.h>
#include <time.h>
#include <malloc.h>
#include <stdlib.h>

//int a[100005];

int random_pos( int left, int right )
{
    srand((unsigned)time(NULL));
    return rand()%( right - left +1 ) + left;
}

int xth_small( int a[], int k, int  left, int right )
{
     if(left >= right)
         return a[left];
    int position = random_pos( left, right );
    int key = a[position],i = left, j = right;
    while( i < j )
    {
        while( i < j && a[i] < key )
        {
            i++;
        }
        while( i < j && a[j] > key )
        {
            j--;
        }
        int temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }
    a[i] = key;
    // xth_small(k,left,position);
    // xth_small(k,position+1, right);
    position = i;
    /**
    printf("%d*\n", position);
    for( int kk = left; kk <= right; kk++ )
        printf("%d ", a[kk]);
    printf("\n");
*/
    if(position == k)
    {
        return key;
    }
    else if( position < k )
    {
        return xth_small(a, k, position+1, right);
    }
    else
    {
        return xth_small(a, k, left, position-1);
    }

}
int main()
{
    int n, k;
    scanf("%d%d", &n, &k);
    int a[n+5];
    for( int i = 0; i < n; i++ )
    {
        scanf("%d", &a[i]);
    }
    //xth_small(k,0, n-1);
    printf("%d\n",xth_small(a,k-1,0,n-1));
/**
    for( int k1 = 0; k1 < n; k1++ )
    {
        printf("%d ", a[k1]);
    }
*/

    return 0;
}

另外

还有一种算法最坏情况下时间复杂度为O(n)。

转:最坏情况为线性时间的选择算法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值