Давайте попробуем представить себе стек (да, есть только один стек) для различных этапов обув вызова (4):
перед вызовом Foo (4): абоненте стек
в пределах первоначального вызова Foo (4): стек = абонент-стек, Foo (4)
, когда Foo (4) находится в пределах первого вызова Foo (2): абоненте-стек, Foo (4), foo (2)
foo (4) в первом вызове foo (2), где foo (2) уже вызвал первый foo (1): caller-stack, foo (4), foo (2), foo (1)
после возвращения из первого Foo (1): снова абонент-стека, Foo (4), Foo (2)
Foo (4) в пределах первого вызова Foo (2), где foo (2) вызвал второй foo (1): caller-stack, foo (4), foo (2), foo (1)
после возвращения из второго foo (1) : Снова абонент-стека, Foo (4), Foo (2)
после возвращения из первого Foo (2): абоненте-стек, Foo (4)
Foo (4) находится в пределах второй вызов Foo (2): абонент-стек, Foo (4), Foo (2)
Foo (4) в пределах второго вызова Foo (2), где Foo (2) уже называется первый foo (1): caller-stack, foo (4), foo (2), foo (1)
после возвращения из первого Foo (1): снова абонент-стека, Foo (4), Foo (2)
Foo (4) в пределах второго вызова Foo (2), где Foo (2) имеет называется второй Foo (1): абонент-стека, Foo (4), Foo (2), Foo (1)
после возвращения из второго Foo (1): снова абонент-стека, Foo (4) , Foo (2)
после возвращения из второго Foo (2): абонент-стек, Foo (4)
после возвращения из Foo (4): вызывающих стек
Это очень окольный путь написания 'Int а = п;' – molbdnilo
Да проблема была изначально о временной сложности функции .. – novalain