线性时间的选择 - 求第K大(小)的数

虽是读书笔记,但是如转载请注明出处http://segmentfault.com/blog/exploring/
..拒绝伸手复制党


以下内容是算法导论第九章的学习笔记。

1 求最大/小值

最优即O(n),比较n-1

2 同时求最大值和最小值

最直白的是O(2n),比较2n-2次。还有一个优化的方法是成对的比较,把较小的与min比较,较大的与max比较。这样每对元素需要3次比较

javapublic int[] maxmin(int array[]){
        int max = 0;
        int min = 0;
        int result[]={0,0};
        //奇数个元素
        if(array.length % 2 == 0){
            if(array[0]>=array[1]){
                max = array[0];
                min = array[1]; 
                }
            else{
                max = array[1];
                min = array[0]; 
                }
            int time = array.length/2 -1;
            result = compare(array,0, min, max,time);
        }
        //偶数个元素
        if(array.length %2 == 1){
            min = max = array[0];
            int time = array.length/2;
            result = compare(array,-1, min, max,time);
        }
        return result; 
    }
    public int[] compare(int array[],int start,int min, int max,int time){
        for(int i=1;i<=time;i=i+1){
            int left = start+2*i;
            int right = start+2*i+1;
            if(array[left] <= array[right]){
                if(array[left]<min){
                    min = array[left];
                }
                if(array[right]>max){
                    max = array[right];
                }
            }

            else if(array[left] > array[right])
                if(array[right]<min){
                   min = array[right];
                }
                if(array[left]>max){
                    max = array[left];
                }
            }
            int result[] = new int[2];
            result[0] = min;
            result[1] = max;
            return result;
    }

以期望线性时间做选择

性能:平均O(n) 最坏O(n^2)
借鉴快速排序每次partition的返回的结果是已排序的性质。

伪代码:

cRANDOMIZED-SELECT ( A, p, r, i )
if  p = r           // 临界问题处理
       then  return A[p]
q ← RANDOMIZED-PARTITION( A, p, r )   //进行划分,返回划分元下标
k ← q – p + 1
if  i = k
       then return A[q];
else if i < k
        then return RANDOMIZED-SELECT ( A, p, q - 1, i )
else 
         return RANDOMIZED-SELECT( A, q+1, r, i – k )

最坏情况线性时间的选择

类似RandomizedSelect算法,通过对输入数组进行递归划分来找出所求元素,但是算法保证每次对数组的划分是个好划分

算法思想

step1 - step3 通过寻找中位数,使得对数组的划分是一个好的划分。

为什么要选择中位数作为划分的pivot number?

快速排序性能最好的时候是:数组的输入序列是均匀的[而非正序或者逆序],即每次递归都是:主元左端和右端的元素个数都一样,那么主元就是中位数。据此,我们可以改进 partition, 每次划分的位置都和中位数的位置相比,递归向下调用。

对快速排序最坏的时候的情况进行优化

快速排序对主元的划分决定了其运行时间,如果最坏是Ο(nlgn),那么就不允许出现极端划分情况。因为我们学习了最坏时间了线性的选择算法,我们何不利用其每次选择都选中位数作为主元的方法来避免极端情况的发生?既然每次都选择中位数作为主元,那么其递归运行时间总是 T(n)=2T(n/2)+Ο(n) 这样根据主方法 case 2 知道 T(n)=Ο(nlgn)。


想更一进步的支持我,请扫描下方的二维码,你懂的~
图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值