分治与递归-找k个临近中位数的数

Posted DNE

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分治与递归-找k个临近中位数的数相关的知识,希望对你有一定的参考价值。

问题描述:给定由n个互不相同的数组成的集合S以及正整数k≤n,试设计一个O(n)时间算法找出S中最接近S的中位数的k个数。

算法描述:

  1. 用线性时间选择实现的算法找到中位数
  2. S’=除去中位数外的S
  3. S"=|S‘中的数值-中位数的值|
  4. 用线性时间选择实现的算法找到第k个最小的数
  5. 输出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个临近中位数的数的主要内容,如果未能解决你的问题,请参考以下文章

选第k小元素:分治策略

分治与递归-棋盘覆盖问题

分治与递归-线性时间选择

LeetCode 4. Median of Two Sorted Arrays (分治)

递归与分治法

7-2 找第k小的数 (20分) —— 分治算法