Чтобы оценить сложность, давайте сосредоточимся на число рекурсивных вызовов, выполняемых, пусть C(n)
.
Вызов для n
подразумевает точно 2(n-1)
рекурсивных звонков, каждый из которых добавляет свои собственные расходы, 2(C(1)+C(2)+...C(n-1))
.
За звонок для n+1
подразумевается точно 2n
рекурсивных звонков, каждый из которых добавляет собственные расходы, 2(C(1)+C(2)+...C(n-1)+C(n))
.
По разнице C(n+1)-C(n) = 2+2C(n)
, которая может быть написана C(n) = 2+3C(n-1)
.
C(1) = 0
C(2) = 2+2C(1) = 2+3C(0) = 2
C(3) = 4+2(C(1)+C(2)) = 2+3C(2) = 8
C(3) = 6+2(C(1)+C(2)+C(3)) = 2+3C(3) = 26
C(4) = 8+2(C(1)+C(2)+C(3)+C(4)) = 2+3C(4) = 80
...
C(n) = 2n-2+2(C(1)+C(2)+...C(n-1)) = 2+3C(n-1)
Для того, чтобы решить эти рецидивы легко заметить, что
C(n)+1 = 3(C(n-1)+1) = 9(C(n-2)+1) = ...3^(n-2)(C(2)+1) = 3^(n-1)
Следовательно, для n>1
точной формулы
C(n) = 3^(n-1)-1
Количество вызовов к Catalan(1)
(постоянное времени), также C(n)
, а числа добавлений или умножений - C(n)/2
каждый.
Легко уменьшить сложность от O(3^n)
к O(2^n)
, отметив, что все члены в петле (кроме среднего) вычисляются дважды - но это еще не делает его приемлемым реализацию :)
Там конечно, случаи, когда вы не можете их использовать, но для нахождения вычислительной сложности рекурсивных функций я хотел бы изучить [рекуррентные отношения] (http://www.cs.duke.edu/~ola/ap/recurrence. html) и [Мастер-теорема] (http://en.wikipedia.org/wiki/Master_theorem). – nchen24
Эта функция даже не заканчивается? Вызов каталанский (n), затем в цикле, когда i = 0, вы вызываете каталанский (n) снова. – nhahtdh
Да, вы правы, я исправил его. – Amen