分治与递归-找k个临近中位数的数
Posted DNE
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分治与递归-找k个临近中位数的数相关的知识,希望对你有一定的参考价值。
问题描述:给定由n个互不相同的数组成的集合S以及正整数k≤n,试设计一个O(n)时间算法找出S中最接近S的中位数的k个数。
算法描述:
- 用线性时间选择实现的算法找到中位数
- S’=除去中位数外的S
- S"=|S‘中的数值-中位数的值|
- 用线性时间选择实现的算法找到第k个最小的数
- 输出S”中小于第k个最小的数的数对应的S中的值
算法实现:
selectorder函数、partition函数、sord函数同线性时间选择程序的算法实现,故略。 int main() { void sord(int a[],int h,int t); int selectorder(int x,int a[],int h,int t); int partition(int a[],int h,int t,int k); int n; scanf("%d",&n); int *a; a=(int *)malloc(sizeof(int)*n); for(int i=0;i<n;i++) a[i]=rand(); for(int i=0;i<n;i++) printf("%d ",a[i]); //动态分配数组a //随机生成数组a元素、输出 /* int n=7; int a[7]={0,-1,20,-4,-100,2000,2001}; for(int i=0;i<n;i++) printf("%d ",a[i]); */ printf("\n"); int middle; middle=selectorder((n-1)/2,a,0,n-1); printf("%d\n",middle); //找到数组a中的中位数并赋值给middle int *b; b=(int *)malloc(sizeof(int)*n); for(int i=0;i<n;i++) if(a[i]>=middle)b[i]=a[i]-middle; else b[i]=middle-a[i]; //动态分配数组b //数组b中元素=|数组a中元素-middle| int *c; c=(int *)malloc(sizeof(int)*n); for(int i=0;i<n;i++)c[i]=b[i]; //数组c中元素=数组b中元素 int k; scanf("%d",&k); //输入k int last; last=selectorder(k-1,b,0,n-1); //找到数组b中第k小元素并赋值给last for(int i=0;i<n;i++) if(c[i]<=last)printf("%d ",a[i]); //遍历数组c,如果数组c中元素小于last, //则输出对应位置上数组a的元素 printf("\n"); sord(a,0,n-1); for(int i=0;i<n;i++)printf("%d ",a[i]); return 0; }
以上是关于分治与递归-找k个临近中位数的数的主要内容,如果未能解决你的问题,请参考以下文章