2010-09-26 3 views
0

La fonction récursive définie comme ceci:Est-ce que ces deux fonctions factorielles s'exécutent dans O (n)?

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

Et itérative ici:

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

J'avais lu que la fonction récursive du corps est O (1) et les appels récursifs O (n 1) en faisant O (n), mais pour l'itératif est-ce O (n) aussi?

+1

'Fonction factorielle ($ x) {pour ($ y = $ x; $ y--> 1; $ x * = $ y); return $ x; } ': PHP est si gentil. (Espérons que je n'ai pas fait de faute: D) – NikiC

+0

'! 0 = 1' (pas' 0') –

Répondre

8

Oui, les deux versions s'exécutent en heure O (n). Le raisonnement de la version itérative est fondamentalement le même que pour la version récursive: Le corps de la boucle s'exécute en O (1) fois et est exécuté n fois.

Cependant, il est à noter que la version itérative s'exécute dans l'espace O (1), tandis que la version récursive utilise l'espace de pile O (n) (car il y a une profondeur de récursivité de n).

+2

+1, implémentation factorielle comme fonction récursive = échec. – erenon

+0

C'est parfait pour ma réponse en fait, j'avais juste besoin de savoir pourquoi sur mon benchmark cette récursive était bien plus lente que l'autre. Je vais mettre ça dans mes notes. – John

+0

On peut refactoriser l'approche récursive pour permettre l'appel de queue et ainsi être aussi O (1) dans l'espace. Mais cela le rend moins clair. – Richard

0

oui c'est O (n). Essayez d'imaginer combien d'opérations le processeur exécutera lorsque vous avez une grande valeur de x. Avec de grandes valeurs, il ne devient pas plus complexe, et c'est toujours la même opération de manière linéaire.

+1

En fait, pour le processeur, ce n'est pas 'O (n)' car la multiplication n'est pas 'O (1)' opération. Mais si vous pensez à la multiplication comme 'O (1)' c'est 'O (n)' –

+0

Je suis content que mes pensées soient justes. Je me suis ennuyé en comparant les deux, la fonction récursive skyrockets au-dessus itérative lors du calcul des factoriels plus élevés. Je me demandais juste s'ils étaient tous deux O (n) indépendamment de ce résultat. Là encore, je suis stupide et j'utilise PHP pour le faire. C'est peut-être pourquoi c'est beaucoup plus élevé. – John

+1

La multiplication sur les types de données primitifs est O (1). Tant qu'il est plus petit qu'un entier de 64 bits, ce sera O (1). Mais oui, si c'est un type entier de précision arbitraire, alors vous avez raison. Mais les deux algorithmes se multiplient. Cela ne les distinguera pas. Créer le cadre de pile pour chaque appel successif dans la version récursive va certainement le ralentir. – JoshD

Questions connexes