(p124)k分位数

  首先,这个题意思应该是:对一个包含n个元素的集合来说,k分位数是指能把有序集合分成k个等大小集合的k-1个顺序统计量,给出一个能找出某一集合的k分位数的O(nlgk)算法——书上多印了一个“第”字,搞得莫名其妙-_-;

  好吧,既然清楚了,我们来分析以下复杂度,lgk——这说明很有可能要用到分治,再根据递归树模型,我们就可以看出来,大概有这样一个函数:find(int *num,int k,int l,int r,int *result),它的功能是找到第(l+r)/2+1个分隔点对应的顺序统计量,存到result数组里面,然后递归地对左边和右边的区间进行操作。怎么找那个顺序统计量?这一章提到的两种算法都可以,而且这两种算法都顺带将数组分为了小于分割数的一部分和大于分割数的一部分,这保证了这道题分治算法的正确性。

/*
 * source.c
 *
 *  Created on: Feb 16, 2016
 *      Author: wing
 */
#include<stdio.h>
#include<stdlib.h>
int Select(int *num,int m,int l,int r)
{
	int i,j=l-1,tmp;
	if (l==r)
		return num[l];
	for (i=l;i<=r-1;i++)
		if (num[i]<num[r])
		{
			j++;
			tmp=num[j];
			num[j]=num[i];
			num[i]=tmp;
		}
	j++;
	tmp=num[j];
	num[j]=num[r];
	num[r]=tmp;
	if (m-1==j)
		return num[j];
	else
		if (m-1<j)
			return Select(num,m,l,j-1);
		else
			return Select(num,m,j+1,r);
}
int find(int *num,int k,int l,int r,int *result)/*注意哦,这里的k是每个小区间有k个元素^-^*/
{
	result[(l+r)/2]=Select(num,((l+r)/2+1)*k,l*k,(r+2)*k-1);
	if (l==r)
		return 0;
	else
	{
		find(num,k,l,(l+r)/2,result);
		find(num,k,(l+r)/2+1,r,result);
		return 0;
	}
}
int main(void)
{
	int *num,n,k,i,*result;
	scanf("%d",&n);
	scanf("%d",&k);
	num=(int *)malloc(sizeof(int)*n);
	for (i=0;i<n;i++)
		scanf("%d",&num[i]);
	result=(int *)malloc(sizeof(int)*k);
	find(num,n/k,0,k-2,result);
	for (i=0;i<=n/k-2;i++)
		printf("%d ",result[i]);
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值