最简单的方法就是N中的每个数分别和max,min比较,看似2N次比较,其实大于max的就不必和min比较,小于min的也不必和max比较,因此比较的次数不足2N次,程序如下:

[cpp] view plaincopy

  1. bool MaxMin(std::vector<T> array, T* max, T* min) {
  2. if (array.size() < 1) {
  3. return false;
  4. }
  5. *max = array[0];
  6. *min = array[0];
  7. size_t array_size = array.size();
  8. for (int i = 1; i < array_size; ++i) {
  9. if (array[i] > *max) {
  10. 10.       *max = array[i];
  11. 11.     } else if (array[i] < *min) {
  12. 12.       *min = array[i];
  13. 13.     }
  14. 14.   }
  15. 15.   return true;

16. }

其次方法是数组中的一对一对的数相互比较,比较中较大的一个和max比较,较小的和min比较,总计有N/2对数,分别和max和min进行一次比较,共计3N/2次比较,程序代码如下:

[cpp] view plaincopy

  1. template<typename T>
  2. bool MaxMin_1(std::vector<T> array, T* max, T* min) {
  3. if (array.size() < 1) {
  4. return false;
  5. }
  6. *max = array[0];
  7. *min = array[0];
  8. int index = 1;
  9. int array_size = array.size();
  10. 10.   while(index < array_size && index +1 <array_size) {
  11. 11.     if (array[index] >= array[index + 1]) {
  12. 12.       if (array[index] > *max) {
  13. 13.         *max = array[index];
  14. 14.       }
  15. 15.       if (array[index + 1] < *min) {
  16. 16.         *min = array[index + 1];
  17. 17.       }
  18. 18.     } else {
  19. 19.       if (array[index + 1] > *max) {
  20. 20.         *max = array[index + 1];
  21. 21.       }
  22. 22.       if (array[index] < *min) {
  23. 23.         *min = array[index];
  24. 24.       }
  25. 25.     }
  26. 26.     index += 2;
  27. 27.   }
  28. 28.   if (index < array.size()) {
  29. 29.     if (array[index] > *max) {
  30. 30.       *max = array[index];
  31. 31.     }
  32. 32.     if (array[index] < *min) {
  33. 33.       *min = array[index];
  34. 34.     }
  35. 35.   }
  36. 36.   return true;

37. }

最后一种方法是分治法,比较次数也是3N/2,程序如下:

[cpp] view plaincopy

  1. template<typename T>
  2. bool MaxMin_2(std::vector<T> array, int start, int end, T* max, T* min) {
  3. if (end - start > 1) {
  4. MaxMin_2(array, start, (start + end) / 2, max, min);
  5. MaxMin_2(array, (start + end) / 2 + 1, end, max, min);
  6. else {
  7. if (array[end] > array[start]) {
  8. if (array[end] > *max) {
  9. *max = array[end];
  10. 10.       }
  11. 11.       if (array[start] < *min) {
  12. 12.           *min = array[start];
  13. 13.       }
  14. 14.     } else {
  15. 15.       if (array[start] > *max) {
  16. 16.         *max = array[start];
  17. 17.       }
  18. 18.       if (array[end] < *min) {
  19. 19.         *min = array[end];
  20. 20.       }
  21. 21.     }
  22. 22.   }

23. }

24. template<typename T>

25. bool MaxMin_3(std::vector<T> array, int start, int end, T* max, T* min) {

  1. 26.   if (end > start) {
  2. 27.     MaxMin_2(array, start, (start + end) / 2, max, min);
  3. 28.     MaxMin_2(array, (start + end) / 2 + 1, end, max, min);
  4. 29.   } else {
  5. 30.     if (array[start] > *max) {
  6. 31.       *max = array[start];
  7. 32.     }
  8. 33.     if (array[start] < *min) {
  9. 34.       *min = array[start];
  10. 35.     }
  11. 36.   }

37. }

为了测试性能,完成比较程序如下:

[cpp] view plaincopy

  1. #include <stdio.h>
  2. #include <vector>
  3. #include <stdlib.h>
  4. #include <sys/time.h>
  5. template<typename T>
  6. bool MaxMin(std::vector<T> array, T* max, T* min) {
  7. if (array.size() < 1) {
  8. return false;
  9. }
  10. 10.   *max = array[0];
  11. 11.   *min = array[0];
  12. 12.   size_t array_size = array.size();
  13. 13.   for (int i = 1; i < array_size; ++i) {
  14. 14.     if (array[i] > *max) {
  15. 15.       *max = array[i];
  16. 16.     } else if (array[i] < *min) {
  17. 17.       *min = array[i];
  18. 18.     }
  19. 19.   }
  20. 20.   return true;

21. }

22. template<typename T>

23. bool MaxMin_1(std::vector<T> array, T* max, T* min) {

  1. 24.   if (array.size() < 1) {
  2. 25.     return false;
  3. 26.   }
  4. 27.   *max = array[0];
  5. 28.   *min = array[0];
  6. 29.   int index = 1;
  7. 30.   int array_size = array.size();
  8. 31.   while(index < array_size && index +1 <array_size) {
  9. 32.     if (array[index] >= array[index + 1]) {
  10. 33.       if (array[index] > *max) {
  11. 34.         *max = array[index];
  12. 35.       }
  13. 36.       if (array[index + 1] < *min) {
  14. 37.         *min = array[index + 1];
  15. 38.       }
  16. 39.     } else {
  17. 40.       if (array[index + 1] > *max) {
  18. 41.         *max = array[index + 1];
  19. 42.       }
  20. 43.       if (array[index] < *min) {
  21. 44.         *min = array[index];
  22. 45.       }
  23. 46.     }
  24. 47.     index += 2;
  25. 48.   }
  26. 49.   if (index < array.size()) {
  27. 50.     if (array[index] > *max) {
  28. 51.       *max = array[index];
  29. 52.     }
  30. 53.     if (array[index] < *min) {
  31. 54.       *min = array[index];
  32. 55.     }
  33. 56.   }
  34. 57.   return true;

58. }

59. template<typename T>

60. bool MaxMin_2(std::vector<T> array, int start, int end, T* max, T* min) {

  1. 61.   if (end - start > 1) {
  2. 62.     MaxMin_2(array, start, (start + end) / 2, max, min);
  3. 63.     MaxMin_2(array, (start + end) / 2 + 1, end, max, min);
  4. 64.   } else {
  5. 65.     if (array[end] > array[start]) {
  6. 66.       if (array[end] > *max) {
  7. 67.         *max = array[end];
  8. 68.       }
  9. 69.       if (array[start] < *min) {
  10. 70.           *min = array[start];
  11. 71.       }
  12. 72.     } else {
  13. 73.       if (array[start] > *max) {
  14. 74.         *max = array[start];
  15. 75.       }
  16. 76.       if (array[end] < *min) {
  17. 77.         *min = array[end];
  18. 78.       }
  19. 79.     }
  20. 80.   }

81. }

82. template<typename T>

83. bool MaxMin_3(std::vector<T> array, int start, int end, T* max, T* min) {

  1. 84.   if (end > start) {
  2. 85.     MaxMin_2(array, start, (start + end) / 2, max, min);
  3. 86.     MaxMin_2(array, (start + end) / 2 + 1, end, max, min);
  4. 87.   } else {
  5. 88.     if (array[start] > *max) {
  6. 89.       *max = array[start];
  7. 90.     }
  8. 91.     if (array[start] < *min) {
  9. 92.       *min = array[start];
  10. 93.     }
  11. 94.   }

95. }

  1. 96.

97. int GetTime() {

  1. 98.   timeval tv;
  2. 99.   gettimeofday(&tv, NULL);
  3. 100.   return tv.tv_sec * 1000000 + tv.tv_usec;

101. }

102. int main(int argc, char** argv) {

  1. 103.   const int kArraySize = 10000;
  2. 104.   std::vector<int> array;
  3. 105.   for (int i = 0; i < kArraySize; ++i) {
  4. 106.     array.push_back(rand());
  5. 107.     //    printf("%d ", array[i]);
  6. 108.   }
  7. 109.   printf("\n");
  8. 110.   int max;
  9. 111.   int min;
  10. 112.   int start;
  11. 113.   start = GetTime();
  12. 114.   MaxMin(array, &max, &min);
  13. 115.   printf("time elapse:%d\n", GetTime() - start);
  14. 116.   printf("max:%d min:%d\n", max, min);
  15. 117.
  16. 118.   start = GetTime();
  17. 119.   MaxMin_1(array, &max, &min);
  18. 120.   printf("time elapse:%d\n", GetTime() - start);
  19. 121.   printf("max:%d min:%d\n", max, min);
  20. 122.   start = GetTime();
  21. 123.   MaxMin_2(array, 0, array.size() - 1, &max, &min);
  22. 124.   printf("time elapse:%d\n", GetTime() - start);
  23. 125.   printf("max:%d min:%d\n", max, min);
  24. 126.   start = GetTime();
  25. 127.   MaxMin_3(array, 0, array.size() - 1, &max, &min);
  26. 128.   printf("time elapse:%d\n", GetTime() - start);
  27. 129.   printf("max:%d min:%d\n", max, min);

130. }

执行结果:

[cpp] view plaincopy

  1. ./a.out
  2. time elapse:187
  3. max:2147469841 min:100669
  4. time elapse:216
  5. max:2147469841 min:100669
  6. time elapse:86513
  7. max:2147469841 min:100669
  8. time elapse:82481

10. max:2147469841 min:100669

结论:最简单的方法效率最高,分治法由于迭代效率非常差,这是我想到了分治法的归并排序,估计性能也不会好,改天比较一下。

寻找数组中的最大值和最小值
《编程之美》2.10
算法1:
if(arr[0] > arr[1])
max=arr[0]
min=arr[1]
else
max=arr[1]
min=arr[0]
loop:i从3到n
if(max < arr[i])
   max=arr[i]
else
   if(min > arr[i])
    min = arr[i]
平均比较次数:1+n-2+(n-2)/2=3*(n-2)/2+1
算法2:
if(arr[0] > arr[1])
max=arr[0]
min=arr[1]
else
max=arr[1]
min=arr[0]
loop:i从3到n(i每次递增2)
if(arr[i] > arr[i+1])
   if(arr[i] > max)
    max=arr[i]
   if(arr[i+1]<min)
    min=arr[i+1]
else
   if(arr[i] < min)
    min=arr[i]
   if(arr[i+1] > max)
    max = arr[i+1]
比较次数:1+3*(n-2)/2
代码:
#include <iostream>

using namespace std;

//algorithm
void maxMin1(int *arr, int b, int e){
int max, min;
if (arr[b] < arr[b+1])
{
   max = arr[b+1];
   min = arr[b];
}else{
   max = arr[b];
   min = arr[b+1];
}

for (int i = b + 2; i < e; i += 2)
{
   if (arr[i] < arr[i +1])
   {
    if (max < arr[i+1])
     max = arr[i+1];
    if (min > arr[i])
     min = arr[i];
   }else{
    if (max < arr[i])
     max = arr[i];
    if (min > arr[i+1])
     min = arr[i+1];
   }
}

if ((e - b)%2)
{
   if (arr[e-1] > max)
    max = arr[e-1];
   if (arr[e-1] < min)
    min = arr[e-1];
}

cout << "max = " << max << ", min = " << min << endl;
}

//algorithm:divide and conquer
void maxMinDivideAndConquer(int *arr, int b, int e, int &max, int &min){
if (e - b == 1)
{
   max = arr[b];
   min = arr[b];
   return;
}

if (e - b == 2)
{
   if (arr[b] < arr[b+1])
   {
    max = arr[b+1];
    min = arr[b];
   }else{
    max = arr[b];
    min = arr[b+1];
   }
   return;
}

int mid = b + (e-b)/2;
int leftMax, leftMin;
maxMinDivideAndConquer(arr, b, mid, leftMax, leftMin);
int rightMax, rightMin;
maxMinDivideAndConquer(arr, mid, e, rightMax, rightMin);

if (leftMax > rightMax)
   max = leftMax;
else
   max = rightMax;

if (leftMin < rightMin)
   min = leftMin;
else
   min = rightMin;
}

void main(){
int arr1[] = {6, 5, 8, 3, 9, 7};
int arr2[] = {6, 5, 8, 3, 9, 7, 20};
// maxMin1(arr1, 0, 6);
// maxMin1(arr2, 0, 7);
int max, min;
maxMinDivideAndConquer(arr1, 0, 6, max, min);
cout << "max = " << max << ", min = " << min << endl;
maxMinDivideAndConquer(arr2, 0, 7, max, min);
cout << "max = " << max << ", min = " << min << endl;
}

扩展问题:要找出N个数组中的第二大数。
法1:通过n-1次比较,找出最大数;在除去最大数的数组中找最大数。比较次数:n-1+n-2=2n-3
法2:把数组中的元素每两个分为一组,每组中的最大数为F,第二大数为S。假设现在已知相邻两组的最大数和第二大数分别是:Fi,Si,Fj,Sj,。则这两组合并为一组后,其中最大数和第二大数可能是:
1、若Fi > Fj,则最大数是Fi;
若Si>Fj,则第二大数是Si;否则,第二大数是Fj
2、若Fi < Fj,则最大数是Fj
若Fi>Sj,则第二大数是Fi;否则,第二大数是Sj
共有N/2组,每组需要比较一次得出本组的最大数和第二大数;共需比较N/2 * 2次。
法3.、分治法divide and conquer
把数组分成两部分,其最大数和第二大数分别是:Fleft,Sleft,Fright,Sright。合并时的情况可能为:
1、Fleft > Fright,最大数是Fleft;若Sleft>Fright,则第二大数是Sleft,否则第二大数是Fright;
2、 Fleft < Fright,最大数是Fright;若Fleft>Sright,则第二大数Fleft,否则第二大数是Sright。
算法如下:
secondMax(int begin, int end, int F, int S)
if(begin + 1 == end)
   if(a[begin] > a[end])
    F = a[begin]
    S = a[end]
   else
    F = a[end]
    S = a[begin]
int mid = begin + (end - begin)/2;
secondMax(begin, mid, Fleft, Sleft)
secondMax(mid+1, right, Fright, Sright)
if(Fleft > Fright)
   F = Fleft
   if(Sleft > Fright)
    S = Sleft
   else
    S = Fright
else
   F = Fright
   if(Fleft > Sright)
    S = Fleft
   else
    S = Sright
比较次数:设n=2^(k+1)
F(n)=2*F(n/2)+2
=2*( 2*F(n/2^2) + 2) + 2
=2^2 * F(n/2^2) + 2^2 + 2
=2^2 * (2*F(n/2^3) + 2) + 2^2 +2
=2^3*F(n/2^3) + 2^3 + 2^2 + 2
=2^k * F(n/2^k) + 2^k + 2^(k-1) + …+ 2^2 + 2^1
=2^k*F(2)+2^k+2^(k-1)+…+2^2+2^1
=2^(k+1)+2^k+…+2^1
=2*n-2

寻找数组中最大值和最小值

解法一:

扫描一次数组找出最大值;

再扫描一次数组找出最小值。

代码(略)

比较次数2N-2

解法二:

将数组中相邻的两个数分在一组, 每次比较两个相邻的数,将较大值交换至这两个数的左边,较小值放于右边。

对大者组扫描一次找出最大值,对小者组扫描一次找出最小值。

代码(略)

比较1.5N-2次,但需要改变数组结构

解法三:

每次比较相邻两个数,较大者与MAX比较,较小者与MIN比较,找出最大值和最小值。

代码如下:

void GetMaxAndMin(int* arr, int len, Result* rlt)
{
    for(int i=2; i< len-1; i=i+2)
    {
        if(NULL==arr[i+1])
        {
            if(arr[i]>rlt->Max)
                rlt->Max=arr[i];
            if(arr[i]<rlt->Min)
                rlt->Min=arr[i];
        }
        if(arr[i]>arr[i+1])
        {
            if(arr[i]>rlt->Max)
                rlt->Max=arr[i];
            if(arr[i+1]<rlt->Min)
                rlt->Min=arr[i+1];
        }
        if(arr[i]<arr[i+1])
        {
            if(arr[i+1]>rlt->Max)
                rlt->Max=arr[i+1];
            if(arr[i]<rlt->Min)
                rlt->Min=arr[i];
        }
    }
}

比较次数1.5N-2,但是不用改变原数组结构。

解法四:

分治法,算出前N/2个数的MAX和MIN,再算出后N/2个数的MAX和MIN。代码如下:

void GetMaxAndMin1(int* arr, int len, Result* rlt)
{
    if(len==0||!arr)
        return;
    if(len==1)
    {
        if(arr[0]>rlt->Max)
            rlt->Max=arr[0];
        if(arr[0]<rlt->Min)
            rlt->Min=arr[0];
        return;
    }
    GetMaxAndMin(arr, len/2, rlt);
    GetMaxAndMin(&arr[len/2], len-len/2, rlt);
}

需比较1.5/N-2次。

试验代码:

#include "stdio.h"
#include "stdlib.h"

#define LEN(arr) sizeof(arr)/sizeof((arr)[0])

struct Result{
    int Max;
    int Min;
};

int main()
{
    int test[10]={3,2,4,1,5,2,7,9,0};
    Result* rlt = (Result*)malloc(sizeof(Result));
    rlt->Max = rlt->Min = test[0];
    int len=LEN(test);
    GetMaxAndMin(test, len, rlt);
    printf("Max=%d\nMin=%d\n", rlt->Max, rlt->Min);
    getchar();
}

寻找数组中 的最大值最小值相关推荐

  1. 编程之美2.10 寻找数组中的最大值和最小值

    这个问题其实很容易解决,就是循环遍历一遍数组,然后找到数组中存在的最大值和最小值就可以了,书中主要讨论的问题是比较次数较小的方法,不过,书中已经证明了,无论用什么方法最少的比较次数也就是循环遍历一遍的 ...

  2. 寻找数组中的最大值和最小值

    解法1. 我们可以吧数字中的最大值和最小值看成两个独立的问题分别求出数组中的最大值和最小值. 直接的方法就是扫描数字,找到最大数以及最小数. <span style="font-siz ...

  3. 蓝桥杯——寻找数组中的最大值

    问题描述 对于给定整数数组a[],寻找其中最大值,并返回下标. 输入格式 整数数组a[],数组元素个数小于1等于100.输入数据分作两行:第一行只有一个数,表示数组元素个数:第二行为数组的各个元素. ...

  4. 编程之美2.10:寻找数组中的最大值和最小值

    编程之美2.10: 对于一个有N个整数组成的数组,需要比较多少次才能把最大值和最小值找出来呢? 算法的思想是: 分而治之 测试数据:---------------------------------- ...

  5. 数组中的最大值/最小值

    For 循环 一般关于实现数组的某种操作,可能最先想到的就是 for 循环吧!下面是它的实现. let min = arr => {let greatest = arr[0]for (let i ...

  6. 编程之美-寻找数组中的最大值和最小值方法整理

    [试题描述] 方法一:比较2N次 方法二:比较1.5N次 方法三:比较1.5N次 方法四:分治法,比较1.5N次

  7. 编程之美4:求数组中的最大值和最小值

    方法1:暴力方法 遍历一遍数组,比较2*N次求出最大值和最小值 方法2:改进方法 (破坏了原数组)             遍历一遍数组使得下标为偶数的元素较下标为奇数的元素大,再分别求出最大值和最小 ...

  8. 基于递归寻找数组中的最大数字

    问题描述:寻找数组中的最大数字: # 寻找数组中的最大值,这个写法真的可以啊 def find_max(arr):# 先找基线条件if len(arr) == 0:return -1if len(ar ...

  9. Java 数组中找最大值和最小值

    题目描述 计算并输出一维数组中的最大值和最小值. 输入描述 输入一个具有8个数的一维数组 输出描述 输出该数组中的最大值和最小值 输入样例 19.8 12.3 45 67.6 23 15.98 2.5 ...

最新文章

  1. QCOW2 — Overview
  2. 【Crash Course Psychology】1. Intro to psychology笔记
  3. 在Qt中如何使用QtDesigner创建的UI文件(一) (转)
  4. MTDDL——美团点评分布式数据访问层中间件
  5. Oracle中Cursor介绍
  6. 存储新技术之“连续数据保护(CDP)”
  7. kotlin实现继承_Kotlin程序| 继承的例子
  8. 初探Golang(1)-变量
  9. linux如何修改用户标识符,linux 修改文件标识符
  10. 基于Minio和Thumbor搭建独立图片服务
  11. Node.js与io.js那些事儿
  12. JAVA绘制图片原理_java开发_图片截取工具实现原理
  13. 手把手带你玩摄像头模组
  14. Shiro框架的搭建与使用
  15. 简单html,用CSS设计一个留言板
  16. 傅里叶变换(时域频域)
  17. 用打印服务器打印 打印机显示脱机,打印机提示脱机使用,无法打印,该怎么解决?...
  18. 小学身高体重测试软件,儿童身高体重在线测评
  19. MySQL中怎么对varchar类型排序问题(数字字符串和汉字拼音的顺序)
  20. 华为云数据迁移工具解决方案:阿里云迁移到华为云

热门文章

  1. settings.xml的配置
  2. java属性绑定_java基础:10.1 Java FX与属性绑定
  3. 各层作用_OSI模型中各层在通信中的作用
  4. 如何评价,为何程序员被骂立马就辞职呢?
  5. 中专学历就该被拒之门外?做Java开发改变命运难吗?
  6. 想学人工智能从哪入手?
  7. 你需要的前端进阶书籍清单,分享下载
  8. JavaScript的历史由来及简介
  9. 学web前端好找工作吗?想给初学者们几点建议
  10. I - 免费馅饼-图画详细解析