Обратный отсчет диапазона рекурсии Javascript

#javascript #function #recursion #range #max

#javascript #функция #рекурсия #диапазон #макс

Вопрос:

 var printRangeUpDown = function(min, max) {
    if (min === max) {
        console.log('condition met '   min);
        return
    }
    console.log('low to high '   min);
    printRangeUpDown(min   1, max);
    console.log('high to low '   min);
};

printRangeUpDown(4, 10);
 

журналы 4,5,6,7,8,9,10,9,8,7,6,5,4

Может кто-нибудь объяснить, почему консоль.журнал ниже printRangeUpDown заставляет его начать запись в журнал в обратном направлении? Я понимаю, что low будет консольным журналом 4,5,6,7,8,9,10 (базовый вариант)… но я не понимаю, почему консольное ведение журнала ниже рекурсивного заставляет его печатать 9,8,7,6,5,4 обратно к min

Ответ №1:

Представьте себе ваш стек рекурсивных вызовов (стек вызовов). Дочерняя функция должна завершиться, прежде чем родительская функция сможет продолжить.

Таким образом, в момент достижения базового варианта (т.Е. min == max) первая половина каждого рекурсивного вызова выполнена, и каждый ожидает возвращения своего дочернего элемента.

Базовый вариант не выполняет рекурсию, он просто возвращает. Теперь выполняется вторая половина каждой функции. Начиная с самого последнего вызываемого ( min = 9 ) и продвигаясь к первому вызываемому ( min = 4 ) . Это называется ЛИФО или Последний вход Первым выходом.

Причина вывода значений заключается в том, что для каждого вызова функции входные аргументы сохраняются до тех пор, пока она не вернется, и поэтому вы видите, что те же значения, которые были напечатаны на пути к базовому варианту, печатаются при возврате к первому вызову функции.

Если мы добавим пробел для каждого рекурсивного вызова, тогда станет просто увидеть, как первый и последний, второй и предпоследний и т.д. Вызов соответствует их значениям.

 4,        // first invocation
 5,       // second
  6,      // third
   7,     // fourth
    8,    // fifth
     9,   // sixth
      10, (base case)
     9,   // sixth
    8,    // fifth
   7,     // fourth
  6,      // third
 5,       // second
4         // first invocation
 

Ответ №2:

Потому что это стек (первый в последнем выходе).

  1. Когда вы вызываете printRangeUpDown(4, 10) с самого начала, он переходит к printRangeUpDown(min 1, max); , программа будет ждать, пока эта функция вернется, чтобы перейти вперед.
  2. Программа переходит к printRangeUpDown(5, 10) тому же, что и выше, подождите printRangeUpDown(6, 10); .
  3. Программа переходит printRangeUpDown(10, 10) , наконец, к первому возврату.
  4. Затем printRangeUpDown(9, 10) вернется, потому (10, 10) что возвращается.
  5. Затем printRangeUpDown(8, 10) вернется, потому (9, 10) что возвращается.
  6. Наконец, printRangeUpDown(4, 10) возвращено.