欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

从无序(互异)数组中找到第K大的数

程序员文章站 2024-03-15 22:18:06
...

1.利用排序算法对其排序,然后直接取出第K个元素——O(nlogn

随机选择算法——可达到O(N)级别

  • 在对A[left,right]执行一次randpartition()后,主元A[p]左侧元素都小于主元,主元右侧元素都大于主元,且主元A[p]是第p-letf+1大的元素。当p>K时,在A[left,p-1]找第K大元素,、;当p==K时,找到;当p<K时,在A[p+1,right]找第K-p大元素
#include<cstdio>
#include<algorithm>
#include<ctime>
#include<cstdlib>
#include<cmath>
const int max=1000;
using namespace std;
double round(double r)//因为c++没有自带的round()四舍五入函数
{
    return (r > 0.0) ? floor(r + 0.5) : ceil(r - 0.5);
}
int  randPartition(int(&a)[max],int low,int high){//这里数组大小需要标明
	//left,high内生成随机数p 
	int p=(int)(round(1.0*rand()/RAND_MAX*(high-low)+low));//!!! 取随机数太复杂啦!!
	swap(a[p],a[low]);
	//
	int t=a[low];
	while(low<high){
		while(low<high&&a[high]>t)high--;
		a[low]=a[high];
		while(low<high&&a[low]<=t) low++;
		a[high]=a[low];	
	}
	a[low]=t;
	return low;
}
int randSelect(int (&a)[max],int left,int right,int K){//!!除了引用外,**还可以设置全局变量**
	//递归边界
	if(left==right) return a[left]; 
	int p=randPartition(a,left,right);
	int m=p+1;//下标所处的位置 
	if(K==m) return a[p];
	else if(K>p) return randSelect(a,p+1,right,K-m);
	else return randSelect(a,left,p-1,K);
	 
}
int main(){
	//生成随机数种子
	srand((unsigned)time(NULL)); 
	int n;
	scanf("%d",&n);
	for(int i=0;i<n;i++){
		scanf("%d",&a[i]);
	}
	int K=3;
	printf("%d",randSelect(a,0,n-1,K));
	return 0;
	
}

出自算法笔记

相关标签: 算法笔记