SHAOXIAOJ正在加载中...

2615: 分治策略-改进的线性时间选择(每5个一组)

金币值:3 定数:6 时间限制:1.000 s 内存限制:128 M
正确:4 提交:4 正确率:100.00% 命题人:
点赞量:0 收藏量:0 题目类型:程序 知识点: 算法设计

题目描述

从一个长度为n的线性表中选择第k(1<=k<=n)个小元素,要求使用线性时间复杂度。

测试代码   复制

#include <stdio.h>

int partition(int a[], int low, int high, int x) {
	int i = low;
	int j = high;
    for(int k=low; k<=high; k++){ 
    // 查找x并与a[low]进行交换 
    	if(a[k]==x){
    		int t=a[k];
			a[k]=a[low];
			a[low]=t; 
			break;
		}
	}
	while (i<=j) {
		while(i<=j && a[i]<=x) i++;
		while(i<=j && a[j]>x) j--;
		if(i<j) {
			int temp=a[i];
			a[i]=a[j];
			a[j]=temp;
		}
	}
	a[low]=a[j];
	a[j]=x;
	return j;
}

void bubble(int a[],int low,int high) { 
    // 对low到high之间的元素进行简单选择排序 
	int i,j;
	for(i=low; i<=high-1; i++) {
		int index=i;
		for(j=i+1; j<=high; j++)
			if(a[j]<a[index]) index=j;
		int t=a[i];
		a[i]=a[index];
		a[index]=t;
	}
}

int select(int a[],int low,int high,int k) {
	if(high-low+1<10) { 
        // 递归出口,如果不足10个元素则直接排序之后得到结果 
		bubble(a,low,high);
		return a[low+k-1];
	}

    //每组5个元素,不足5个元素的最后一组暂时不考虑
	for(int i=0; i<=(high-low-4)/5; i++) {
		
	}

	//寻找中位数的中位数
	int x=select(a,low,low+(high-low-4)/5,(high-low+1)/10); 
	int i=partition(a,low,high,x);
	int length=i-low+1;

	if(k<=length)
	{
		return select(a,low,i,k);
	} 
	else
	{
		return select(a,i+1,high,k-length);
	}
	
}

int main(void) {
	int a[100],i,n,k;
	scanf("%d",&n);
	for(i=0; i<=n-1; i++) scanf("%d",&a[i]);
	scanf("%d",&k);
	int result=select(a,0,n-1,k);
	printf("%d\n",result);
	return 0;
}

输入格式

第1行输入一个整数n,表示线性表中有n个数据
第2行输入n个整数,表示线性表中的具体数据
第3行输入一个整数k

输出格式

第4行输出第k个小元素的值

输入样例    复制

22
11 13 12 14 15 16 17 19 18 20 21 1 2 3 4 5 6 7 8 9 10 -1
12

输出样例    复制

11