Завершается ли он в первую очередь?
Для n == 0
он просто возвращается. Но для n == 1
он будет называть себя для n == 0
, n == 1
и n == 2
. Таким образом, вызов a(1)
вызовет еще один вызов a(1)
...
IOW, это бесконечный l oop и покажет бесконечную сложность.
Теперь после изменение алгоритма будет прекращено. Итак, позвольте мне исследовать это заново.
Для n == 1
он будет вызывать себя только с n == 0
.
Для n == 2
он будет вызывать себя для n == 0
, n == 1
и еще n == 0
из-за n == 1
; это делает 3 звонка.
Для n == 3
он будет звонить сам 3 раза + 3 раза + 1 раз, делает 7 раз.
Для n == 4
он будет звонить 4 раза + 7 раз + 3 раза + 1 раз, получается 15 раз.
Это очень похоже на O (2 ^ n - 1) = O (2 ^ n).
(Это легко доказать по индукции; количество вызовов будет 2 ^ n - 1, что, очевидно, верно для всех приведенных выше примеров. Учитывая, что это верно для некоторых n, из этого легко будет сделать вывод, что это верно для n + 1)
Поскольку доказательство по индукции не является очевидным для ОП, здесь оно выглядит так:
Прежде всего, поскольку кроме l oop внутри функции ничего не происходит, оно ' Я добавлю только постоянное количество операций на итерацию, что означает, что будет достаточно подсчитать количество вызовов к себе.
Выше, это доказано для n = 1
.
Сейчас Предположим, что это было доказано для некоторых n
. Теперь мы будем следовать, что это верно для n + 1
.
По индукционной гипотезе количество вызовов для a(n + 1) = n + 1 + \sum_{i=0}^n (2^i - 1)
(извините за обозначения; это сработало бы для mathexchange. В нем говорится «сумма для я иду от 0 до n из (2 ^ i - 1) ").
Теперь n + 1 + \sum_{i=0}^n (2^i - 1) = \sum_{i=0}^n (2^i) = 2^{n + 1} - 1
, который должен был быть показан.
Это доказывает, что сложность O (2 ^ п).