Ответ 1
Анализ рекурсивных функций (или даже их оценка) является нетривиальной задачей. A (на мой взгляд) хорошее введение можно найти в Don Knuths Concrete Mathematics.
Однако проанализируйте эти примеры сейчас:
Определим функцию, которая дает нам время, необходимое для функции. Скажем, что t(n)
обозначает время, необходимое для pow(x,n)
, т.е. Функцию n
.
Тогда мы можем заключить, что t(0)=c
, потому что, если мы вызываем pow(x,0)
, мы должны проверить, ((t25 > )), а затем вернуть 1, что можно сделать в постоянное время (следовательно, константа c
).
Теперь рассмотрим другой случай: n>0
. Здесь мы получаем t(n) = d + t(n-1)
. Это потому, что мы снова проверили n==1
, вычислим pow(x, n-1
, следовательно (t(n-1)
) и умножим результат на x
. Проверка и умножение могут выполняться в постоянное время (константа d
), для рекурсивного вычисления pow
требуется t(n-1)
.
Теперь мы можем "развернуть" термин t(n)
:
t(n) =
d + t(n-1) =
d + (d + t(n-2)) =
d + d + t(n-2) =
d + d + d + t(n-3) =
... =
d + d + d + ... + t(1) =
d + d + d + ... + c
Итак, сколько времени потребуется, пока мы не достигнем t(1)
? Поскольку мы начинаем с t(n)
и мы вычитаем 1 на каждом шаге, для достижения t(n-(n-1)) = t(1)
требуется n-1
шагов. Это, с другой стороны, означает, что мы получаем n-1
раз константу d
, а t(1)
оценивается как c
.
Итак, получаем:
t(n) =
...
d + d + d + ... + c =
(n-1) * d + c
Итак, мы получаем, что t(n)=(n-1) * d + c
, являющийся элементом O (n).
pow2
можно выполнить с помощью теоремы Мастера. Поскольку мы можем предположить, что функции времени для алгоритмов монотонно возрастают. Итак, теперь у нас есть время t(n)
, необходимое для вычисления pow2(x,n)
:
t(0) = c (since constant time needed for computation of pow(x,0))
для n>0
получаем
/ t((n-1)/2) + d if n is odd (d is constant cost)
t(n) = <
\ t(n/2) + d if n is even (d is constant cost)
Вышеуказанное может быть "упрощено":
t(n) = floor(t(n/2)) + d <= t(n/2) + d (since t is monotonically increasing)
Итак, мы получаем t(n) <= t(n/2) + d
, который может быть решен с использованием магистерской теоремы для t(n) = O(log n)
(см. раздел "Применение к популярным алгоритмам" в ссылке wikipedia, пример "Бинарный поиск" ).