基于快速排序算法找第k小的元素

 首先是跟快排一样的分区函数

//--------------------分区函数--------------------
int Partition(int a[],int l,int r){	
	int pivot=a[l];	//取开头元素为枢轴 
	while(l<r){
		while(l<r&&a[r]>=pivot)	//如果a[r]大于等于pivot的话r就一直向前走 
			r--;
		a[l]=a[r];	//直到小于pivot就让a[l]等于a[r],然后移动l指针 
		while(l<r&&a[l]<pivot)	//如果a[l]小于pivot的话l就一直向后走 
			l++;
		a[r]=a[l];	//直到大于pivot就让a[l]等于a[r]
	}
	a[l]=pivot;	//循环结束后l的位置就是pivot的位置 
	return l;	//返回pivot的最终位置 
}

找第k大元素实现 

int Find_kmin(int a[],int l,int r,int k){
	if(l<r){
		int i=Partition(a,l,r);
		if(i==k)	//如果分区函数返回的位置刚好是k,因为是升序排序,说明a[i]就是第k小的元素 
			return a[i];
		else if (i<k)	//如果分区函数返回的位置小于k,说明第k小的数在a[i]的右边 
            return Find_kmin(a,i+1,r,k);	//舍弃左边,继续搜索右边 
        else
            return Find_kmin(a,l,i-1,k);	//否则舍弃右边,继续搜索左边 
	}
	return a[l];//当l=r时还没有返回值的话表示当前只有一个元素,无须再分区,直接返回a[l] 
} 

如果先对整个序列进行快排然后输出a[k]时间复杂度为O(nlogn)

但是我们只需要找第k小的元素,所以没必要对所有元素进行排序,跟快排不同的是,上述算法每次只需要对左、右分区中的一个进行分区,即n+n/2+n/4+....1,所以时间复杂度为O(n)

同理我们可以写出找第k大元素的代码 

int Find_kmax(int a[],int l,int r,int k,int len){	//len是序列长度 
	if(l<r){
		int i=Partition(a,l,r);
		if(i==len-k)
			return a[i];
		else if (i<len-k)
            return Find_kmax(a,i+1,r,k);
        else
            return Find_kmax(a,l,i-1,k);
	}
	return a[l];
} 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Genius256

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值