最大最小元素

/**
 * -*- coding : utf-8 -*-
 * @Author : huangshengjiang
 * @Email : 1005542693@qq.com
 * @Date : 2016-10-20 10:08
 * @Last Modified Date : 2016-10-24 15:51     
 * @FileName :   最大最小元素.cpp
 */

/*最大最小元素
    基本概念 : 用分治的思想快速找出数组A中的最大和最小元素. 
              (分治思想是将原问题转化为若干相互独立的子问题,
               再加子问题结果结合起来,成为原问题的求解)
    应用场景 : 1.快速找出数组的数值表示范围/区间.建立有效直观的图表
               2.数组是抽象的概念,实际上要看数组所代表的现实意义.
    具体需求 : 快速找出数组A的最大最小元素
        输入 : 无序数组A[1..n]
        输出 : (x,y) 分别是数组A的最大元素和最小元素

    分析 : 明确一点,该算法的性能主要是依赖比较次数和交换次数成正比的(O(比较)+O(交换)),两者开销不一样,其中比较开销小,交换开销大.
            无论用什么办法要找出数组中的最大最小元素,都需要至少比较依次数组中的每一个元素,
            比较次数至少为2n次,关键就在于如何减少交换的次数(占大头). 
            --等等,如果用指针来进行交换(针对大型结构有效,但是对于当前int数组没有必要,因为指针本身占据4个字节,交换与int的开销一样)
            肯定需要至少两个额外空间存放最大最小两个元素.
            问题转换为如何将交换次数尽可能减少的同时比较次数进可能接近2n次?
            
            反正都要进行比较,而交换是根据比较的结果决定是否执行的.那么这其中的关键就是如何确定比较的参照值
            (首次找出较大范围的较小较大的参照值,这就涉及到比较次数的问题,比较次数接近O(2n),无法避免.可以接受)
            问题的关键是快速找出当前数组的较大范围的较小较大参照值?(见方案2)

    解决方案1 : 初始以前两个元素作为暂时的最大最小元素,依次遍历数组,每个数值要和当前最大最小值比较,比较次数接近O(1.75n)
                交换次数接近O(0.75n)这些都是估摸算的,不是很准确.
        优缺点 : 代码易于理解,但是代码执行效率不高,交换次数偏高,舍弃.
        
    解决方案2 : 采用分治递归比较.找出数组的最大最小值.原理: 原数组分为两组,分别计算两组的最小最大元素,进行比较得出最小最大元素.
                而两组的最小最大元素则由下一层的划分求得.递归的基础(到哪里返回):当小组个数为1时,返回最大最小值都是该值, 
        优缺点 : 同级别得到的最小最大元素只要对应比较,能够快速找出较小较大值.减少交换次数.
                 但是要申请额外的空间进行比较,如果递归次数过多,则有可能产生内存泄漏(不足).当然也是当前最好的.

    结论 : 采用分治递归方法.

 */
#include <iostream>
using namespace std;
template <class T>
int Size(T &array)
{
    return sizeof(array)/sizeof(array[0]);
}


//函数
void minmax(int * array,int left ,int right,int &min,int &max)//left左边的坐标,最小为0,right右坐标,最大位n-1.
{
    int cur = right - left ;
    if ( cur == 0 )
    {
        min = max = array[left];
        return ;
    }//递归基础

    int lmin,lmax;
    int rmin,rmax;
    minmax(array,left,left + cur/2,lmin,lmax);
    minmax(array,left + cur/2 + 1,right,rmin,rmax);
    min = lmin <= rmin ? lmin : rmin ;
    max = lmax <= rmax ? rmax : lmax ;
}


//测试
int main(int argc, char const *argv[])
{
    int a[]={1,3,4,4,6,7,5,3,5,45,675,-1};
    int length = Size(a);
    cout << length <<endl;
    int min,max;
    minmax(a,0,length-1,min,max);

    cout<< "最小值" << min << ",最大值" << max <<endl;

    system("pause");
    return 0;
}

转载于:https://www.cnblogs.com/jiangge3/articles/5993328.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值