N个元素中选最大最小

N个元素中选最大最小



问题描述:从N个元素中,选出最大元素和最小元素。分析复杂度。



方法:

方法有三种。


方法一:

最笨的方法,循环一次找出最大的算素。再循环一下找到最小的。这里2次循环可以放在一起,作为小小的优化。比较次数:2* (N – 1) = 2N – 2


代码:

void select_Max_Min_1(int *a,int n,int &Max,int &Min)
{
    int i;
    int kmax,kmin;
    kmax=kmin=0;
    for(i=1; i<n; ++i)
    {
        if(a[i]>a[kmax])  kmax=i;
        if(a[i]<a[kmin])  kmin=i;
    }
    Max=a[kmax];
    Min=a[kmin];

}



方法二:


取前两个元素比较出大小,取较大的元素与其余元素比较,得出最大值;取较小的元素与其余元素比较,得出最小值。


比较次数:1 + 2* (N – 2 + 1 – 1) = 2N – 3


从这里我们可以看出,N个元素比较最大,需要N-1次比较。找出最小也需要N-1次比较。如果2个问题分开看,这是基本的需求。不过,当2个问题放到一起,原先每个问题中解决的子问题是有关系的。即,如果是将2个问题单独的存在时的方法简单的合到一起时(如方法1),里面会有很多重复的操作。如果我们能尽可能的减少这样的操作,方法的复杂度就会降低(如方法2)。

显然,方法2还可以优化。


代码:

void select_Max_Min_2(int *a,int n,int &Max,int &Min)
{
    int i;
    int kmax,kmin;
    if(a[0]>a[1])
    {
        kmax=0;
        kmin=1;
    }
    else
    {
        kmax=1;
        kmin=0;
    }
    for(i=2; i<n; ++i)
    {
        if(a[i]>a[kmax])  kmax=i;
        if(a[i]<a[kmin])  kmin=i;
    }
    Max=a[kmax];
    Min=a[kmin];

}

方法三:


每相邻2个元素比较,较大的放后面,较小的放前面。在较大的元素中,找最大的。在较小的元素中找最小的。

odd:o((3n-3)/2) N为奇数

even:o(3n-4)/2) N为偶数



代码:

///这里注意序号的关系,其余都很好理解。

void select_Max_Min_3(int *a,int n,int &Max,int &Min)
{
    int i,temp;
    int kmin=0,kmax=1;
    if(n%2)     ///奇数
    {
        for(i=0; i<n-1; i+=2)
        {
            if(a[i]>a[i+1])
            {
                temp=a[i];
                a[i]=a[i+1];
                a[i+1]=temp;
            }
        }
        for(i=3; i<n-1; i+=2)
        {
            if(a[i]>a[kmax])    kmax=i;
            if(a[i-1]<a[kmin])  kmin=i-1;
        }
        if(a[kmax]<a[n-1])   kmax=n-1;
        if(a[kmin]>a[n-1])  kmin=n-1;
        Max=a[kmax];
        Min=a[kmin];

    }
    else        ///偶数
    {
        for(i=0; i<n; i+=2)
        {
            if(a[i]>a[i+1])
            {
                temp=a[i];
                a[i]=a[i+1];
                a[i+1]=temp;
            }
        }
        for(i=3; i<n; i+=2)
        {
            if(a[i]>a[kmax])    kmax=i;
            if(a[i-1]<a[kmin])  kmin=i-1;
        }
        Max=a[kmax];
        Min=a[kmin];
    }
}

分析:

N为偶数好分析,就先说偶数情况。

N为偶数时,相邻元素比较N/2次,在每个N/2个元素中分别找最大最小,2* N/2-1)。

共计:N / 2+ 2 * N/ 2 – 1=3N/2 – 2


N为奇数时,N-1为偶数,用偶数方法得出N-1个元素中的最大最小,带入上面的式子。3(N-1) / 2 – 2。剩下一个元素分别与得出的最大最小比较,得出最终的最大最小值。

共计:3(N-1 )/ 2 – 2 + 2 = (3N – 3 ) / 2



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值