带/不带子程序的Javascript中的简单递归

时间:2015-08-30 22:36:27

标签: javascript recursion

我坚持如何在javascript中递归地找到数组的最大值。我先迭代地尝试了它,当然它有效。递归地,我想首先尝试使用子程序,然后没有子程序。在子程序内部调用子程序的最佳方法是什么?我被绊倒的地方是我想要查看索引,但目前我的子例程接受一个数组作为参数。

function maxValue(arr) {
  var max = 0;
  for (var i = 0; i < arr.length; i++) {
    if (arr[i] > max) {
      max = arr[i];
    }
  }
  return max;
}

console.log(maxValue([2, 7, 8, 3, 1, 4])); //returns 8

function maxValueRecursive(arr) {
  var length = arr.length; //6
  var max = 0;


  function doSearch(arr) {
    if (arr.length === 1) {
      max = arr[0];
    } else { // true

      max = Math.max(arr[length - 1], arr[length - 2]);
      //max = Math.max(4, doSearch()) = 4.

    }
    return max;
  }

  return doSearch(arr);
}

console.log(maxValueRecursive([2, 7, 8, 3, 1, 4])) //returns 4

3 个答案:

答案 0 :(得分:2)

您可以使用Math.max并在每一步求解一小部分数组。诀窍是从数组中删除一些(任何)项目,并使用Math.max将项目与较小数组上的findmax进行比较:

function findmax(arr){
    if (arr.length == 1){
        // base case - single item in array is always max
        return arr[0];
    }
    // recursive call on smaller problem (shorter array)
    return Math.max(arr[0], findmax(arr.slice(1)))
}

我使用了slice,但您可以使用pop或其他任何方法删除项目,并使用Math.max进行比较。

对于数组[1, 4, 2, 3],递归展开如下:

1. findmax([1, 4, 2, 3]
2. Math.max(1, findmax([4, 2, 3]))
3. Math.max(1, Math.max(4, findmax([2, 3])))
4. Math.max(1, Math.max(4, Math.max(2, findmax([3]))))
5. Math.max(1, Math.max(4, Math.max(2, 3))) // 4

答案 1 :(得分:1)

我知道一开始感觉很奇怪,但是从内部调用函数就像......从内部调用它一样简单!

下面的函数将数组作为第一个参数,接下来的两个参数是搜索中该点的最大值的索引,以及分别比较最大值的下一个值。首先使用0和1,然后让函数从那里接管。

var findMax = function (array, curMaxIndex, nextIndex) {
    if (array[nextIndex] > array[curMaxIndex]) {
        curMaxIndex = nextIndex;
    }
    if (nextIndex > array.length) {
        return array[curMaxIndex];
    }
    return findMax(array, curMaxIndex, nextIndex + 1);
}

var max = findMax([2, 7, 8, 3, 1, 4, 9], 0, 1);

console.log(max); //9

您还可以设置默认值,因此原始调用更简单:

var findMax = function (array, curMaxIndex, nextIndex) {
    curMaxIndex = typeof curMaxIndex !== 'undefined' ? curMaxIndex : 0;
    nextIndex = typeof nextIndex !== 'undefined' ? nextIndex : 1;
    if (array[nextIndex] > array[curMaxIndex]) {
        curMaxIndex = nextIndex;
    }
    if (nextIndex > array.length) {
        return curMaxIndex;
    }
    return findMax(array, curMaxIndex, nextIndex + 1);
}

var max = findMaxIndex(array);

最好的方法是使用你已经听说过的内置Math.max(),所以我假设这只是一个学习练习。

答案 2 :(得分:1)

如果没有子程序,请考虑单个数组元素的最大值是元素本身。

您想要解决问题,以便可以将输入数组缩减到一个元素,然后开始向后工作并检查是否有更大的元素。

一些伪代码可以帮助您入门:

max (A[1, 2, ..., n])
    if n = 1
        return A[1]
    else
        oldMax <- max([2, ..., n])
        if A[1] > oldMax
            return A[1]
        else
            return oldMax

起初这可能有点令人生畏,但这是一个解释。我们知道如何使用一个元素来获取数组的最大值,所以我们继续进行递归调用,直到我们有一个包含一个元素的数组,但是这里的诀窍是:我们传递给递归调用的数组是相同的数组,但删除了第一个元素。通过这种方式,我们使阵列越来越小,直到只剩下一个元素。然后,我们知道最大值是元素本身。

因此我们获得了单元素数组的最大值,并返回该值。现在,当我们试图找到最大值时,我们会剥离每一层递归。

假设数组为[1, 2, 3, 4]。然后该函数将继续进行递归调用:

max([1, 2, 3, 4])
    max([2, 3, 4])
        max([3, 4])
            max([4]) -> 4

在最后阶段,我们可以返回4,因为那是最大值。但是现在我们回到数组为[3, 4]的阶段。在这个阶段,我们将检查第一个元素3是否大于我们从递归调用4计算的最大值。在这种情况下,它不是,所以我们继续返回4

我们重复此操作,直到我们回到第一层,我们最终返回4,因为1不大于目前为止的最大值4。由于数组中的所有元素都不大于4,因此最大值永远不会改变。