Стек для этой рекурсивной функции будет изначально из-за повторяющихся рекурсивных вызовов, выполненных для вычисления значения a
; то есть, мы будем продолжать называть q1(x/2)
до x/2 < 1
, в этом случае мы достигли базового варианта рекурсии и может просто вернуть 1.
Каждый раз, когда мы вернемся из одного из начальных q1(x/2)
вызовов, затем мы должны следовать вызов q1(x-2)
, который производится для вычисления b
.Этот рекурсивный вызов также будет иметь ряд последовательных рекурсивных вызовов для a
(поскольку a
сначала вычисляется в вашей функции), которые следуют тому же правилу; после возврата каждого из них мы делаем рекурсивный вызов для b
, и этот процесс повторяется, пока мы не достигнем базового аргумента во всех ветвях вызовов.
Вот как выглядел бы стек. Порядок его считывания состоит в том, чтобы следовать вертикальным стрелкам, насколько это возможно, вернуться, а затем следовать по диагональной стрелке. Повторите этот процесс после диагональной стрелки. Когда стрелок не появится, вернитесь.
Кстати, стоп-кадры для возвращенных функций будут полностью освобождены, а новый вызов функции, если он сделан, займет свое место. Вы можете видеть, что в любой момент времени активна не более 4 кадров стека. Когда последний верхний стек стека завершен, он освобождается, а его пятно берется стеком внизу и вправо. Вы вернетесь от этого и так далее ...
Надеюсь, эта схема поможет разобраться.
| | |
| | |
| | |
+--------+ | | |
| a = | | | |
| b = | | | |
+--------+ | | |
| x = 0 |
+--------+
returns 1
^ +--------+
| | a = |
| | b = |
| +--------+
| /| x = -1 |
| / +--------+
| / returns 1
| /
+--------+/
| a = 4 |/
| b = 3 |/
+--------|
| x = 1 |
+--------+
returns 7
^ +--------+
| | a = |
| | b = |
| +--------+
| /| x = 0 |
| / +--------+
| / returns 1
| /
+--------+/
| a = 10 |/
| b = 3 |/
+--------+
| x = 2 |
+--------+
returns 13
^ +--------+
| | a = |
| | b = |
| +--------+
| | x = 0 |
| +--------+
| returns 1
|
| ^ +--------+
| | | a = |
| | | b = |
| | +--------+
| | /| x = -1 |
| | / +--------+
| | / returns 1
| | /
| +--------+/
| | a = 4 |/
| | b = 3 |/
| +--------+
| | x = 1 |
| +--------+
| returns 7
|
| ^ +--------+
| | | a = |
| | | b = |
| | +--------+
| | | x = 0 |
| | +--------+
| | returns 1
| |
| | ^ +--------+
| | | | a = |
| | | | b = |
| | | +--------+
| | | /| x = -1 |
| | | / +--------+
| | | / returns 1
| | | /
| | +--------+/
| | | a = 4 |/
| | | b = 3 |/
| | +--------+
| | /| x = 1 |
| | / +--------+
| | / returns 7
| | /
| | /
| +--------+/
| | a = 10 |/
| | b = 15 |
| +--------+
| /| x = 3 |
| / +--------+
| / returns 25
| /
+--------+/
| a = 16 |/
| b = 51 |/
+--------+ | | |
| x = 5 | | | |
+--------+ | | |
returns 67 | | |
| | |
| | |
| | |
У Brofessor хороший теоретический подход, но что-то, что он говорит, немного неточен; когда он говорит, что q1(x/2)
рекурсирует быстрее, чем q1(x-2)
, он означает, что первый быстро достигнет базового блока по сравнению с последним. Подумайте о больших количествах, чем 5. При больших значениях x
x/2
намного меньше x-2
. Таким образом, корпус x-2
заканчивается тем, что делает намного больше рекурсивных вызовов, чем случай x/2
, поэтому вызовы x-2
доминируют над ростом стека.
Например, у q1(64)
будет 7 рекурсивных вызовов для q1(x/2)
(64/2, 32/2, ..., 1/2 = 0). Но у него будет так много рекурсивных вызовов для q1(x-2)
(64-2, 62-2, 60-2, ..., 2-2 = 0).
В его чертеже было бы более реалистичным, если бы правильное поддерево было больше, потому что это поддерево займет намного больше времени. Фактически, это можно увидеть на моей диаграмме. Если вы считаете вертикальные и диагональные стрелки ветвями дерева, поддерево для самого первого рекурсивного вызова с использованием x/2
имеет только 5 узлов, а поддерево для самого первого рекурсивного вызова с использованием x-2
имеет 7 узлов. Это почти всегда будет иметь место.
Вы спрашиваете о фактическом вызове и о том, как выполняются стековые фреймы, или о вертикальной высоте дерева рекурсии? –
Фактическое соглашение о вызове – dewanc36
Вы должны запустить это через отладчик, чтобы вы могли видеть вывод каждого вызова метода и сколько раз вы вызывали этот метод. – MeetTitan