C ++递归地找到数组的最小值

时间:2018-04-26 02:28:37

标签: c++ recursion

我有一个c ++编程类的作业,用于在不使用静态变量的情况下编写递归函数,使用以下原型: int findmin(const int a [],int n);

我的解决方案适用(对于非常小的数组),但我认为~2 ^ n复杂度过高并且可以改进。

是否可以在指定标准内进行任何改进,以提高效率?

int findmin(const int a[], int n)
{
    if(n == 0)
        return a[0];
    else
    {
        if(a[n-1] < findmin(a,(n-1)))
            return a[n-1];
      else
            return findmin(a,(n-1));
    }
}

2 个答案:

答案 0 :(得分:5)

担心效率有点傻,因为在O(n)中有一个明显的,非递归的方式,一次通过。甚至有一个STL算法std :: min_element。但是,这是一个愚蠢的任务。首先要确保您的解决方案是正确的。当n == 0时,a [0]是否有效?通常,这样的#include <algorithm> #include <cassert> int findmin(const int a[], int n) { assert(n>0); if(n == 1) // See heyah. return a[0]; else { return std::min(a[0], findmin(a + 1, n - 1)); } } 表示数组的长度,而不是最低的索引。

要从O [n ^ 2]转到O [n],请务必仅比较每个元素一次。这意味着不会在每次传递时从数组的开头开始。

int findmin(const int a[], int n) {
    if(n<=0) { throw std::length_error("findmin called on empty array");}
    return *std::min_element(a, a+n);
}

在for-real C ++代码中,如果由于某种原因我们背负旧时尚功能签名,我们会做这样的事情:

{{1}}

答案 1 :(得分:3)

您可以执行条件运算符?:来删除一堆if else语句,以使函数更清晰。而不是两次调用findmin(),你可以将返回值赋给语句中的变量,这是此代码与原始代码的主要优势。

int findmin(const int a[], int n) {
   if (n == 0) // base case
      return a[0];

   return a[n] < (int min = findmin(a, n - 1)) ? a[n] : min;
}

这个(a[n] < (int min = findmin(a, n - 1)) ? a[n] : min;)也可以使用if语句完成:

if (a[n] < (int min = findmin (a, n - 1))
     return a[n];
else
     return min;

编辑: 根据许多信誉良好的来源,这是O(n)时间。 O(n ^ 2)将是我们将每个元素与所有其他元素进行比较。