zoukankan      html  css  js  c++  java
  • 34. 在序列中查找最大值(递归手法)

    一. 问题

    给定一组序列,找出其中的最大元素。

    二. 实例分析

    1.循环手法

    (1)思路

    给定一组序列, data = (1, 3, 4, 9, 12, 3)。我们一眼看出,最大值是 12 ,但是计算机并不能一眼看出。我们用一个变量来保存最大值,并将序列中的每个元素与之比较,如果大于这个最大值,就将它赋值给最大值,否则不用理会,继续处理下一个。

    (2)代码实现

     1 int find_max(const vector<int>& data) {
     2     const int MIN = numeric_limits<int>::min();
     3     int max = MIN;
     4 
     5     for (auto& x : data) {
     6         if (x > max) {
     7             max = x;
     8         }
     9     }
    10 
    11     return max;
    12 }

    不难看出,算法的时间复杂度为O(n)。只需要查看一遍序列,就能够找到最大值(要找最小值也是同理)。但是如果需要多次查找,这样就不划算了,每次都要查看所有的元素,显然做了很多的无用功。在这种情况下,我们应该先将序列排序,然后就能直接找到对应元素。排序的时间复杂度是O(nlogn),因为我们用的是快速排序。

    (3)算法正确性证明

    最开始,令 max 是小于元素中所有序列的值,那么第一次循环, max 的值必将是序列首元素的值。在前 n 次迭代中,max 的值也是这 n 个元素中的最大值,那么到序列末尾,结束循环以后,max 的值必将保存的是整个序列的最大值。(此处证明用的是数学归纳法)

    2. 递归手法

    (1)思路

    当序列只有一个元素时,最大值就是这个元素,这就是基准情况。如果序列有多个元素,我们需要逐步削减,直到元素个数为 1(不是真的削减,只是将参数减少 1 而已),这是层层深入。等到序列只有 1 个元素时,我们就可以将该元素返回,然后与上一个元素作比较,找到一个最大的,这是层层返回。

    (2)代码实现

    1 int find_max_recursive(const vector<int>& data, int n) {
    2     if (n == 1) {
    3         return data[n];
    4     }
    5 
    6     return max(find_max_recursive(data, n- 1), data[n - 1]);
    7 }

    (3)算法正确性证明

    现在我们分析一下这段代码。不难看出,第 2-4 行就是基准情况,只有一个元素时直接返回结果。第 6 行就是返回并进行比较,选出一个最大的元素。先把最后一个元素留下,因此是 data[ n - 1 ],再进行层层深入,传入的还是那个序列,只不过大小少了一个(将最后一个元素排除在外)。这样返回的时候,是第一个元素和第二个元素比较,选出一个大的,然后依次向后推。最后一次是第 n - 1 个元素和第 n 个元素比较,留下一个大的,那么算法结束以后,得到的结果必将是整个序列当中的最大值。

  • 相关阅读:
    SpringMvc
    Spring-Aop
    Spring-IOC
    Spring模块划分
    队列
    稀疏数组
    数据结构
    Nginx配置实例
    Nginx常用命令
    视频断点播放:h5+jquery
  • 原文地址:https://www.cnblogs.com/Hello-Nolan/p/13548097.html
Copyright © 2011-2022 走看看