随机选择算法

如何从一个无序数组中求出第K大的数(假设数组中的数各不相同)。例如,对数组{5,12,7,2,9,3}来说,求第2大的数为9。
最直接的想法是对数组进行排序,然后取出第K个元素即可。但这样做的时间复杂度为O(nlogn),而随机选择算法,他对任何输入都可以达到O(n)的期望时间复杂度。
随机选择算法的原理类似于随机快速排序算法。当对A[left,right]执行一次randPartition函数后,主元左侧的元素个数就是确定的,且他们都小于主元。假设此时主元是A[P],那么A[P]就是A[left,right]中的第p-left+1大的数。不妨令M表示p-left+1,那么如果K==M成立,说明第K大的数就是主元A[P]。

int randPartition(int A[],int left,int right){
	//生成[left,right]内的随机数p 
	int p=round(1.0*rand()/RAND_MAX*(right-left)+left);
	swap(A[p],A[left]);		//交换A[p]和A[left] 
	int temp=A[left];		//将A[left]存放至临时变量temp 
	while(left<right){		//只要left与right不相遇 
		while(left<right&&A[right]>temp)	//反复左移right 
			right--;
		A[left]=A[right];		//将A[right]挪到A[left] 
		while(left<right&&A[right]<=temp)	//反复右移left 
			left++;
		A[right]=A[left];		//将A[left]挪到A[right] 
	}
	A[left]=temp;		//把temp放到left与right相遇的地方 
	return left;
}  
int randSelect(int A[],int left,int right,int K){
	if(left==right)			//边界 
		return A[left];		//划分后主元位置为p 
	int p=randPartition(A,left,right);		//A[p]是A[left,right]中的第M大 
	int M=p-left+1;		 
	if(K==M)			//找到第K大的数
		return A[p];
	if(K<M)			//第K大的数在主元左侧 
		return randSelect(A,left,p-1,K);
	else			//第K大的数在主元右侧 
		return randSelect(A,p+1,right,K-M);
} 

需要加上头文件#include<algorithm>

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值