线性时间选择

问题:给定线性序集中n个元素和一个整数k,1<=k<=n,要求找出这n个元素中第k小的元素。

我们采用快速排序的思想来解决这个问题。首先我们要找到基准的位置,如果基准的位置小于k,则表示第k小的元素在基准的后面,否则在基准的前面。

如果能在线性时间内找到一个划分基准,使得按这个基准所划分出的2个子数组的长度都至少为原数组长度的 ε 倍(0<ε<1是某个常数),那么就可以在最坏情况下用O(n)时间完成选择任务。

算法过程如下:

  • 将这个函数定义为select(nums,p,r,k),即为找到nums[p:r]数组中第k(1<=k<=n)小的元素。
  • 假如数组的长度小于75,那么直接用快排来解决。
  • 将n个输入元素划分成ceil(n/5)个组,每组5个元素,只可能有一个组不是5个元素。用任意一种排序算法,将每组中的元素排好序,并取出每组的中位数,共ceil(n/5)个。
  • 递归调用select来找出这ceil(n/5)个元素的中位数。如果ceil(n/5)是偶数,就找它的2个中位数中较大的一个。以这个元素作为划分基准。

在这里插入图片描述

//一次快排
int Partition(int nums[],int p,int r,int x)
{
	if(p>r) return -1;
	//找出基准x的位置并与第一位交换 
	for(int i=p;i<=r;i++)
	{
		if(nums[i]==x)
		{
			swap(x,nums[p]);
			break;
		}
	}
	int left=p,right=r;
	while(left<right)
	{
		while(left<right && nums[right]>=x) right--;
		nums[left]=nums[right];
		while(left
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值