1. 程式人生 > >分治與遞歸-找k個臨近中位數的數

分治與遞歸-找k個臨近中位數的數

pan sele %d selector 隨機生成 數組 第k小元素 正整數 rand

問題描述:給定由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個臨近中位數的數