简体   繁体   中英

Simple Recursion in Javascript with/without a subroutine

I'm stuck on how to find the max value of an array recursively in javascript. I tried it first iteratively and of course it works. recursively, I wanted to try it with a subroutine first, and then without a subroutine. What's the best way to call the subroutine inside itself? Where I am getting tripped up is that I want to look inside the indices, but currently my subroutine accepts an array as a parameter.

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

You can use Math.max and solve for a smaller bit of the array at each step. The trick is to remove some (any) item from the array and use Math.max to compare the item with findmax on the smaller array:

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)))
}

I used slice but you can use pop or whatever method to remove an item and compare it using Math.max as I did.

For the array [1, 4, 2, 3] the recursion unfolds as follows:

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

I know it feels weird at first, but calling a function from within itself is as simple as... well, calling it from within itself!

The below function takes the array as the first parameter, the next two parameters are the indices of the max value at that point in the search and the next value to compare the max value to respectively. You start off by using 0 and 1 and then let the function take over from there.

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

You could also set up default values, so the original call is more simple:

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);

The best way though is to use the built in Math.max() , which it appears you've already heard of, so I'm assuming this is just a learning exercise.

For doing it without a subroutine, consider that the maximum of a one-array element is the element itself.

You want to break down the problem such that you can get the input array down to one element, and then start working backwards and checking if there are any larger elements.

Some pseudocode to get you started:

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

This may be a bit intimidating at first, but here's an explanation. We know how to get the maximum of an array with one element, so we keep doing the recursive call until we have an array with one element, But here's the trick: the array we pass into the recursive call is the same array, but with the first element removed. This way, we're making the array smaller and smaller until there's only one element left. Then, we know that the maximum is the element itself.

So we get the maximum of the one-element array, and we return that value. Now we're peeling back each layer of recursion as we try to find the biggest value.

Say the array is [1, 2, 3, 4] . Then the function will keep making recursive calls like this:

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

At the last stage, we can return 4 since that's the maximum. But now we're back at the stage where the array is [3, 4] . At this stage, we will check to see if the first element, 3 , is bigger than the maximum we computed from the recursive call, 4 . In this case, it isn't, so we keep returning 4 .

We repeat this until we're back at the first layer, where we finally return 4 since 1 is not greater than the maximum so far, 4 . Since none of the elements in the array are greater than 4 , the maximum never changed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM