线性时间选择

        查找 n 个元素中第 k  小元素,其基本思路是对输入数组进行递归划分,模仿快排的算法,不同点在于,它只对划分出的子数组之一进行递归处理。可认为问题是在 O(n)  的时间内得到解决的。

        此算法也比较常用于求中位数

#include<stdio.h>
#include<stdlib.h>
// 线性时间选择, 查找数组中第 k 小元素
// 基于快速排序算法,每次划分后只对其中一个子数组进行递归排序
#define Type int
Type a[10];

void Swap( Type &x, Type &y)
{
	Type t;
	t = x;
	x = y;
	y = t;
}
Type RandomizedPartion(Type a[], int p, int r)
{
	int i = rand()%(r-p+1) + p, j = r+1;
	Type x = a[i];
	Swap(a[i], a[p]);
	i = p;
	while(1)
	{
		while(a[++i] < x && i < r)
		{}
		while(a[--j] > x && j > p)
		{}
		if(i >= j)
			break;
		Swap(a[i], a[j]);
	}
	a[p] = a[j];									// 只能这样做,假如不事先把 a[p] 单独拿出来,不然直接交换结束后,i 和 j 到底哪个指的是值为 x 的,是不确定的
	a[j] = x;
	return j; 
}
Type RandomizedSelect(Type a[], int p, int r, int k)
{
	if(p == r)
		return a[p];								// 注意喽,函数返回值是第 k 小元素的值,不是位置==!
	int i = RandomizedPartion(a, p, r);
	int j = i - p + 1;								// a[i] 是第 j 小的元素
	if(k <= j)										// 通过判断,只对子数组之一进行递归处理
		return RandomizedSelect(a, p, i, k);
	else
		return RandomizedSelect(a, i+1, r, k-j);
}

int main()
{
	int i;
	printf("Please enter 10 elements:");
	for( i = 0; i < 10; i++)
		scanf("%d", &a[i]);
	i = RandomizedSelect( a, 0, 9, 2);
	printf("%d\n", i);
	i = RandomizedSelect( a, 0, 9, 4);
	printf("%d\n", i);
	return 0;
}


 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值