web-dev-qa-db-fra.com

Complexité spatiale de la fonction récursive

Étant donné la fonction ci-dessous:

int f(int n) {
  if (n <= 1) {
    return 1;
  }
  return f(n - 1) + f(n - 1);
} 

Je sais que la complexité temporelle de Big O est O(2^N), car chaque appel appelle la fonction deux fois.

Ce que je ne comprends pas, c'est pourquoi la complexité espace/mémoire est O(N)?

21
George Kagan

Une façon utile d'aborder ces types de problèmes est de penser à arbre de récursivité . Les deux caractéristiques d'une fonction récursive à identifier sont:

  1. La profondeur de l'arborescence (combien au total déclarations de retour seront exécutées jusqu'au cas de base)
  2. La largeur de l'arbre (combien total appels de fonctions récursives seront effectués)

Notre relation de récurrence pour ce cas est T(n) = 2T(n-1). Comme vous avez correctement noté la complexité temporelle de O(2^n) mais regardons-la en relation avec notre arbre de récurrence.

      C
     / \         
    /   \      
T(n-1)  T(n-1)

            C
       ____/ \____
      /           \
    C              C   
   /  \           /  \
  /    \         /    \
T(n-2) T(n-2) T(n-2)  T(n-2)

Ce modèle se poursuivra jusqu'à notre scénario de base qui ressemblera à comme ceci .

À chaque niveau d'arbre successif, notre n diminue de 1. Ainsi, notre arbre aura une profondeur de n avant d'atteindre le cas de base. Puisque chaque nœud a 2 branches et que nous avons n niveaux totaux, notre nombre total de nœuds est 2^n Ce qui rend notre complexité temporelle O(2^n).

Notre complexité de mémoire est déterminée par le nombre d'instructions de retour car chaque appel de fonction sera stocké sur la pile de programmes. Pour généraliser, la complexité de la mémoire d'une fonction récursive est O(recursion depth). Comme le suggère notre profondeur d'arbre, nous aurons n déclarations de retour total et donc la complexité de la mémoire est O(n).

32
Ritwik Biswas