选择问题算法

对于给定的n 个元素的数组A 1 : n ),要求从中找出第k小的元素。如果划分元素v测定在Aj)的位置上,则有j-1个元素小于或等于Aj),且有n-j个元素大于或等于Aj)。因此,若k<j,则第k小元素在A1j-1)中;若k=j,Aj)就是第k小元素;若k>j,则第k小元素是Aj+1n)中第(k-j)小元素。所导出的算法如果成SELECT。此过程把第k小元素放在Ak),并划分剩余的元素,使得Ai)≤Ak),1i<kAi)≥Ak),k<in

         算法13   找第k小元素

procedure  SELECT(A,n,k)

 //在数组A1),…,A(n)中找第k小元素s并把它放在位置k,假设1≤k≤n。将剩下的元素按如下方式重新排列,使A(k)=t,对于1≤m<t,有A(m)≤t;对于k<m≤n,有A(m)≥t。A(n+1)=+ //

   integer  n,k,m,r,j;

   m<—1 ; r<— n+1; A(n+1) <—+无穷 ;

   loop     //每当进入这一循环时,1mkn+1//

      j r  //将剩余元素的最大下标加1后置给j//

      call  PARTITION(m,j)   //返回j,它使得Aj)是第j小的值//

      case

        :k=jreturn

        :k<jr j    //j是新的上界//

        :elsem j+1   //j+1是新的下界//

      endcase

   repeat

end  SELECT

C语言代码:

/*选择问题:找第K小的元素*/

#include <stdio.h>

/*快速排序中的划分函数,其中数组array的最后一个数要为无穷大,last为这个数的下标加一,也就是最后一个元素的下标加一;first为数组的第一个元素的下标*/

int partition (int array[], int first, int last){

    int v = array[first];

    int m = first;

    int n = last;

    while (1) {

        m = m + 1;

        while (v > array[m]) {

            m++;

        }

        n = n - 1;

        while (v < array[n]) {

            n--;

        }

        if (m < n) {

            int temp = array[m];

            array[m] = array[n];

            array[n] = temp;

        }else{

            break;

        }

    }

    array[first] = array[n];

    array[n] = v;

    return n;

}

/*选择函数,其中n为数组元素个数*/

int select1(int array[],int n, int k){

    int first = 0;

    int last = n;

    int j;

    while (1) {

        j = partition(array, first, last);

        if (j == k-1) {

            break;

        }else if((k-1) < j){

            last = j;

        }else{

            first = j+1;

        }

    }

    return array[j];

}

int main(int argc, char ** argv){

    int arr[7] = {3,5,7,4,1,2,90};

    printf("%d\n",partition(arr, 0, 7));

    for (int i = 0; i < 7; i++) {

        printf("%d ",arr[i]);

    }

    printf("\n%d", select1(arr, 7,1));

    return 0;

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值