打卡第十九天(选择问题)

选择问题(第k小元素)(分治法)

Selection algorithm

选择问题即第k小元素问题。

解决该问题的基本思想与快速排序算法相同,通过选择基元进行划分,从而知道第k小元素在哪里。

原始数据使用随机函数生成。

采用结构化程序设计,可以很容易改为从标准输入或文件读入数据,只需要修改函数getData即可。

数据个数由宏定义给出,也可以轻松地改为输入。

算法有递归与非递归两种过程,非递归过程是正解。

问题描述:从N个数中,选出第k小(排序后排在第k个位置)的元素。

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define N 7
void getData(int [],int);
void result_output(int []);
int selectmink1(int a[],int low,int high,int k);
int selectmink2(int a[],int low,int high,int k);
int split(int a[],int low,int high);
int main(void)
{
    int a[N],k,r;
    getData(a,N);
    result_output(a);
    scanf("%d",&k);
    if(k>=0&&k<=N-1){
        r=selectmink1(a,0,N-1,k);
        printf("result=%d\n",r);
        r=selectmink2(a,0,N-1,k);
        printf("result=%d\n",r);
    }
    else
    printf("input error:k=%d\n",k);
    return 0;
 }
 int selectmink1(int a[],int low,int high,int k)
 {
     int middle;
     middle=split(a,low,high);
     if(middle==k)
    return a[k];
    else if(middle<k)
    return selectmink1(a,middle+1,high,k);
    else/*if(midddle>k)*/
    return selectmink1(a,low,middle-1,k);
 }
 int selectmink2(int a[],int low,int high,int k)
 {
     int middle;
     for(;;){
     middle=split(a,low,high);
     if(middle==k)
    return a[k];
    else if(middle<k)
    low=middle+1;
    else/*if(midddle>k)*/
    high=middle-1;
}
}
int split(int a[],int low,int high)
{
    int part_element=a[low];
    for(;;){
        while(low<high && part_element<=a[high])
        high--;
        if(low>=high)break;
        a[low++]=a[high];
        while(low<high&&a[low]<=part_element)
        low++;
        if(low>=high)break;
        a[high--]=a[low];
    }
    a[high]=part_element;
    return high;
}
void getData(int d[],int n)
{
    time_t t;
    srand((unsigned)time(&t));
    int i;
    for(i=0;i<n;i++)
    d[i]=rand()%100;
}
void result_output(int a[])
{
    int i;
    for(i=0;i<N;i++)
    printf("%d",a[i]);
    printf("\n");
}

 

猜你喜欢

转载自blog.csdn.net/huangluping12345/article/details/83031490
今日推荐