zoukankan      html  css  js  c++  java
  • 最坏情况为线性时间的选择算法

    算法select可以确认一个有n>1个不同元素的输入数组中第i小的元素。(如果n=1,则select只返回它的唯一输入数值作为第i小的元素。)

    1.将输入数组的n个元素划分为n/5(向下取整)组,每组5个元素,则至多只有一组由剩下的n mod 5个元素组成。

    2.寻找这n/5(向上取整)组中每一组的中位数:首先对每组元素进行插入排序,然后确定每组有序元素的中位数。

    3.对第2步中找出的n/5(向上取整)个中位数,递归调用select以找出其中位数x(如果有偶数个中位数,为了方便,约定x是较小的中位数)。

    4.利用修改过的PARTITION版本,按中位数的中位数x对输入数组进行划分。让k比划分的地区中的元素数目多1,因此x是第k小的元素,并且有n-k个元素在划分的高区。

    5.如果i=k,则返回x。如果i<k,则在低区递归调用select来找出第i小的元素。如果i>k,则在高区递归查找第i-k小的元素。

    #include <stdio.h>
    
    #define ARRAY_SIZE 10
    
    int select(int a[], int l, int r, int k);
    int partition(int a[],int p,int r,int pivot);
    void insertsort(int a[], int low, int high);
    void swap(int a[], int i, int j);
    
    int main(void)
    {
        int a[ARRAY_SIZE]={25,31,89,12,67,53,44,59,71,19};
        
        printf("%d
    ",select(a,0,ARRAY_SIZE-1,6));
    }
    
    int select(int a[], int l, int r, int k)
    {
        int group;
        int i;
        int left,right,mid;
        int pivot;
        int p,left_num;
        
        if (r-l+1 <= 5) {
            insertsort(a,l,r);
            return a[l+k-1];
        }
        
        group = (r-l+1+5)/5;
        for(i=0; i<group; i++) {
            left = l+5*i;
            right = (l+5*i+4) > r?r:l+5*i+4; //超出右便捷就使用右边界赋值
            mid = (left+right)/2;
            insertsort(a,left,right);
            //将各组中位数与前i个元素互换位置,方便递归select寻找中位数的中位数
            swap(a,l+i,mid); 
        }
        pivot = select(a,l,l+group-1,(group+1)/2); // 找出中位数的中位数
        
        // 用中位数的中位数作为基准的位置
        p = partition(a,l,r,pivot);
        left_num = p-l;
        if(k == left_num+1)
            return a[p];
        else if(k<=left_num) //k在低区
            return select(a, l, p-1, k);
        else //k在高区
            return select(a, p+1, r, k-left_num-1);
    }
    
    int partition(int a[],int p,int r,int pivot)
    {
        int x;
        int i=p-1;
        int j,tmp;
        
        for (j=p;j<r;j++) {
            if(a[j] == pivot) {
                swap(a,j,r);
            }
        }
        x = a[r];
        
        for(j=p;j<r;j++) {
            if(a[j]<=x) {
                i++;
                tmp=a[i];
                a[i]=a[j];
                a[j]=tmp;
            }
        }
        tmp=a[r];
        a[r]=a[i+1];
        a[i+1]=tmp;
        return i+1;
    }
    
    // 插入排序
    void insertsort(int a[], int low, int high)
    {
        int i,j;
        int key;
        
        for(i=low+1; i<=high; i++) {
            key = a[i];
            for (j=i-1;j>=low&&key<a[j];j--) {
                a[j+1] = a[j];
            }
            a[j+1] = key;
        }
    }
    
    void swap(int a[], int i, int j)
    {
        int tmp=a[i];
        
        a[i] = a[j];
        a[j] = tmp;
    }

    它的时间复杂度为O(n)

  • 相关阅读:
    warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
    Windows10+CLion+OpenCV4.5.2开发环境搭建
    Android解决部分机型WebView播放视频全屏按钮灰色无法点击、点击全屏白屏无法播放等问题
    MediaCodec.configure Picture Width(1080) or Height(2163) invalid, should N*2
    tesseract
    Caer -- a friendly API wrapper for OpenCV
    Integrating OpenCV python tool into one SKlearn MNIST example for supporting prediction
    Integrating Hub with one sklearn mnist example
    What is WSGI (Web Server Gateway Interface)?
    Hub --- 机器学习燃料(数据)的仓库
  • 原文地址:https://www.cnblogs.com/yanxin880526/p/7466743.html
Copyright © 2011-2022 走看看