[C/C++] 用线性时间选择来找无序数组的中位数

该博客探讨了一种在无序数组中寻找中位数的方法,特别是针对大数据量的情况,避免了排序操作。当线的数量为奇数时,问题转化为传统的中位数问题;偶数时则需要特定策略。通过线性时间选择算法,可以在O(n)的时间复杂度内找到中位数。博主提供了具体的程序实现,利用分治策略确定基准并迭代搜索目标位置。

有一道题大概是这样的:有n条水平的线,知道线的纵坐标,选择一条线,使得这条线到所有线的距离之和最小。

根据数学知识,我们知道,如果线是奇数条的话,那么中间那条(纵坐标的中位数)即可,如果是偶数条的话,那么中间那2条区间内的都可以,而如果要线的纵坐标尽可能小,那么就取中间两条纵坐标较小的那条即可。

那么在线数量为偶数的时候,这并不是传统的求中位数问题,而线数量为奇数的时候,则变成传统的中位数问题。

求中位数的方法可以先排序然后直接取中间的一条即可,但是对于大数据量来说,排序不可行。利用线性时间选择可以再O(n)下找到中位数。


线性时间选择将数组分成3部分,一部分是基准(1个数),其他两部分是大于这个基准的数组和小于基准的这个数组,对于长度为n的数组来说,我们目的是找到第k=(1+n)/2个数,那么就可以根据k和基准的关系来判断第二次是在小于基准的数组里查找还是在大于基准里的数组查找。程序如下:

#include<iostream>
using namespace std;
#define MAX 100001
int main()
{
	int a[MAX];
	int *p=a;
	int x,y,t1,n=0;
	char t2;
	cin>>n;
	for(int i=0;i<n;i++) cin>>a[i];
	int* small=new int[n]; //小于中位数的集合
	int* big=new int[n]; //大于中位数的集合
	int equal; //等于中位数的那个数,也就是基准
	int k=(1+n)/2;  //处于数组最中间索引的元素

	while(1)
	{
		int x=p[rand()%n]; //随机选取一个数做基准
		int n_s=0,n_b=0;
		for(int i=0;i<n;i++) //将n个数划分成3组:小的集合,基准,大的集合
		{
			if(p[i]>x) big[n_b++]=p[i];
			else if(p[i]==x) equal=x;
			else small[n_s+
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值