中位数

/*
一组数的中位数,就是把一组数从小到大排好后位居中间的
那一个;如果有奇数个数,那么中位数就是中间的那个;如果
有偶数个数,那么中位数就是中间两个数的平均数。
那么有没有办法不用排序就可以求出中位数的方法呢?
可以回想一下qsort中partition的作用:找出一个分界点,左边的
数都小于分界点值,右边的数都大于分界点值。所以,只要不断地
进行partition,直到分界点是left与right的中央元素就行了。需要
注意的是,还要考虑到有奇数个还是偶数个数的问题。
*/
#include<cstdio>

using namespace std;

void swap(int *a,int *b)
{
	int t=*a;
	*a=*b;
	*b=t;
}

void partition(int A[],int left,int right,int *pos)
{
	int data=A[left];
	int i;
	for(*pos=left,i=left+1;i<=right;i++)
	{
		if(A[i]<data)
		{
			(*pos)++;
			swap(&A[*pos],&A[i]);
		}
	}
	swap(&A[left],&A[*pos]);
}

int Getmid(int A[],int n)
{
	int left=0;
	int right=n-1;
	int mid=(left+right)/2;
	int pos,count=1;
	while(1)
	{
		partition(A,left,right,&pos);
		if(pos==mid)
			break;
		else if(pos>mid)
			right=pos-1;
		else
			left=pos+1; 
		//1th  pos=3   1 5 3 7 11 9
		//2th  pos=0   1 5 3 7 11 9
		//3th  pos=2   1 3 5 7 11 9
	}
	return (n&0x1)!=0?A[mid]:(A[mid]+A[mid+1])/2;
}

int main(int argc,char *argv[])
{
	int Array[]={7,5,3,1,11,9};
	int mid;
	mid=Getmid(Array,sizeof(Array)/sizeof(int));
	printf("The mid number of the array is: %d\n",mid);

	return 0;
}

#include<stdio.h>
#include<stdlib.h>
int n,a[10005];
int find(int qian,int hou,int k)
{
    int i=qian,j=hou;
    int piv=a[hou];
    while(i<j)
    {
        while(a[i]<=piv&&i<j)
            i++;
        if(i<j)
            a[j--]=a[i];
        while(a[j]>=piv&&i<j)
            j--;
        if(i<j)
            a[i++]=a[j];
    }
    a[i]=piv;
    if(i-qian+1==k)
        return a[i];
    else
        if(i-qian+1<k)
            return find(i+1,hou,k-(i-qian+1));
        else
            return find(qian,i-1,k);
}
int main()
{
    int i,j;
    while(scanf("%d",&n)!=EOF&&n)
    {
        for(i=0;i<n;i++)
            scanf("%d",&a[i]);
        j=find(0,n-1,n/2+1);
        if(n%2)
            printf("%d\n",j);
        else
            printf("%d\n",(find(0,n-1,n/2)+j)/2);
    }
    return 0;
}
/**************************************************************
    Problem: 1157
    User: smileyk
    Language: C
    Result: Accepted
    Time:10 ms
    Memory:952 kb
****************************************************************/


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值