2010-09-26 3 views
0

Рекурсивная функция определяется как так:Выполняют ли обе эти факториальные функции в O (n)?

function factrec($x) { 
    if($x <= 1) { 
     return $x; 
    } else { 
     return $x * factrec($x - 1); 
    } 
} 

И итерационный здесь:

function factiter($x) { 
    $y = $x; 
    while($y > 1) { 
     $x *= ($y - 1); 
     $y--; 
    } 
    return $x; 
} 

Я прочитал, что на рекурсивной функции тело O (1) и рекурсивные вызовы O (n- 1) делает его O (n), но для итеративного это O (n) также?

+1

'function factorial ($ x) {for ($ y = $ x; $ y--> 1; $ x * = $ y); return $ x; } ': PHP так хорош. (Надеюсь, я не ошибся: D) – NikiC

+0

'! 0 = 1' (не' 0') –

ответ

8

Да, обе версии работают в O (n) времени. Обоснование итеративной версии в основном та же, что и для рекурсивной версии: тело цикла работает в O (1) раз и выполняется n раз.

Однако следует отметить, что итеративная версия работает в пространстве O (1), в то время как в рекурсивной версии используется пространство стека O (n) (поскольку имеется глубина рекурсии n).

+2

+1, реализация факториала как рекурсивная функция = сбой. – erenon

+0

Это идеальное решение для моего ответа на самом деле, мне просто нужно было знать, почему на моем тесте, что рекурсивный был ТО, намного медленнее, чем другой. Я поставлю это в своих заметках. – John

+0

Можно реорганизовать рекурсивный подход, чтобы разрешить хвостовой вызов и, следовательно, также быть O (1) в пространстве. Но это делает его менее ясным. – Richard

0

Да, это O (n). Попытайтесь представить, сколько операций процессор будет работать, когда у вас есть большое значение x. При больших значениях он не становится более сложным, и он всегда является одной и той же операцией линейным способом.

+1

Фактически, что касается процессора, это не 'O (n)', потому что умножение не 'O (1)' операция. Но если вы думаете о умножении как 'O (1)' это 'O (n)' –

+0

, я рад, что мои мысли были правильными. Мне было скучно, сравнивая эти два, рекурсивная функция skyrockets выше итеративного при вычислении более высоких факториалов .. просто интересно, были ли они оба O (n) независимо от этого результата. Опять же, я глуп и использую PHP для этого .. возможно, поэтому он намного выше. – John

+1

Умножение на примитивные типы данных - O (1). Пока это меньше, чем 64-битное целое число, это будет O (1). Но да, если это произвольный прецизионный целочисленный тип, тогда вы правы. Но оба алгоритма умножаются. Это не изменит их. Создание фрейма стека для каждого последующего вызова в рекурсивной версии, безусловно, замедлит его. – JoshD

Смежные вопросы