从一个数组中同时找出最大最小数-算法导论第九章

(1)首先,从一个数组中找出一个最大或最小值,只需要遍历一次,进行n-1次比较就可以得到

for(int i=0;i<array.length;i++){
if(min>array[i]){
min=array[i];
}

(2)同时取出最大最小值呢,同时意味着只经过一次遍历

实际上,至多只需要3*n/2次就可以了
可以将元素按对来处理,先比较每一对的大小,再把大的和最大值比较,小的和最小值比较。
分奇偶:
奇数个:把最大和最小值都先设为第一个值
偶数个:把最大和最小分别设为前两个数。
实际上就是要保证剩下来比较的是偶数个

public void getMax_Min(int a[]){
        int len=a.length;
        int max=0,min=0;
        int i=0,j=len-1;
        if(len%2==0){
            if(a[0]>a[1])
            {   max=a[0];
                min=a[1];
            }
            else{
                max=a[1];
                min=a[0];
            }
            i=2;//索引从2开始
        }
        else{
            max=a[0];
            min=a[0];
            i=1;
        }

        while(i<j){
            if(a[i]<a[j]){
                max=a[j]>max?a[j]:max;
                min=a[i]<min?a[i]:min;
            }
            else{
                max=a[i]>max?a[i]:max;
                min=a[j]<min?a[j]:min;
            }
            i++;
            j--;
        }
        System.out.println(max+"   "+min);
    }

在线性时间内求出数组a中的第i小(或大)的元素,以小为例:

public int  getRandom_select(int a[],int start,int end,int i){
        if(start==end){
            return a[start];
        }
        int q=Partition(a,start,end);
        //System.out.println("q"+q+"start"+start+"i"+i);
        if((q-start+1)==i){//这里必须要进行q-start+1,不能直接是q,因为i,是变化的,但q是一直是0——a.length最初的索引来算的,所以当是k<i这种情况时候直接用q就是偏大的,看下面粗体
            //System.out.println("q"+q+"  "+i);
            return a[q];
        }
        int k=q-start+1;//表示的是从start到q总共多少元素
        if(k>i)
            return getRandom_select(a,start,q-1,i);
        else {
            return getRandom_select(a,q+1,end,i-k);
        }
    }


    int Partition(int a[],int left,int right)//快速排序的划分,得到枢轴量的下标 
    {
        int i=left;
        int j=right;
        int temp=a[left];
        System.out.println("temp"+temp);
        while(i<j)
        {
            while(i<j && a[j]>=temp)
                j--;
                if(i<j)
                    a[i++]=a[j];
            while(i<j && a[i]<=temp)
                i++;
                if(i<j)
                    a[j--]=a[i];
        }
        a[i]=temp;
        return i;
    }

平均情况下:时间复杂度为o(n),最差就是每一次余下的元素都是按最大的划分出来的,则是o(n^2)

*取第5小
0 8 5 2 4 6 3 19 23 20
第一次划分
Start=0,end =9;
得到q=0;,划分后数组
8 5 2 4 6 3 19 23 20
划分的结果是从a[1]=8开始,这时候应该是取第4小,所以在比较时候就必须q-(现在的)start+1***

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值