9. Récursivité¶
Comprendre la récursivité¶
La récursivité est basée sur deux principes fondamentaux :
- Un ou plusieurs cas de base qui arrêtent la récursion
- Un ou plusieurs cas récursifs qui décomposent le problème
Prenons l’exemple de la suite de Fibonacci où :
- \(F(0) = 0\) (cas de base)
- \(F(1) = 1\) (cas de base)
- \(F(n) = F(n-1) + F(n-2)\) pour \(n > 1\) (cas récursif)
public class ExempleFibonacci {
public static long fibonacci(int n) {
// Cas de base
if (n == 0) return 0;
if (n == 1) return 1;
// Cas récursif
return fibonacci(n - 1) + fibonacci(n - 2);
}
public static void main(String[] args) {
System.out.println("F(5) = " + fibonacci(5));
}
}
Visualisation avec le débogueur¶
Pour visualiser les appels récursifs dans IntelliJ :
- Placez un point d’arrêt sur la ligne du cas récursif
- Démarrez le débogage (
Maj+F9) - Utilisez les commandes suivantes :
F7(Step Into) pour suivre les appels récursifsF8(Step Over) pour exécuter une ligneAlt+F7pour sortir de la méthode courante
public class FibonacciDebug {
public static long fibonacci(int n) {
// Ajoutez cette ligne pour faciliter le débogage
System.out.printf("Calcul de F(%d)%n", n);
if (n == 0) {
System.out.println("Cas de base F(0) = 0");
return 0;
}
if (n == 1) {
System.out.println("Cas de base F(1) = 1");
return 1;
}
// Point d'arrêt ici
long resultat = fibonacci(n - 1) + fibonacci(n - 2);
System.out.printf("F(%d) = %d%n", n, resultat);
return resultat;
}
public static void main(String[] args) {
System.out.println("Début du calcul de F(4)");
long resultat = fibonacci(4);
System.out.println("Résultat final: " + resultat);
}
}
Exemple plus complexe : Tours de Hanoï¶
public class ToursHanoi {
private static int compteurEtapes = 0;
public static void deplacerDisques(int n, char source, char destination, char auxiliaire) {
compteurEtapes++;
// Cas de base
if (n == 1) {
System.out.printf("Étape %d: Déplacer disque 1 de %c vers %c%n",
compteurEtapes, source, destination);
return;
}
// Cas récursifs
// 1. Déplacer n-1 disques de source vers auxiliaire
deplacerDisques(n - 1, source, auxiliaire, destination);
// 2. Déplacer le dernier disque de source vers destination
System.out.printf("Étape %d: Déplacer disque %d de %c vers %c%n",
compteurEtapes, n, source, destination);
// 3. Déplacer n-1 disques de auxiliaire vers destination
deplacerDisques(n - 1, auxiliaire, destination, source);
}
public static void main(String[] args) {
int nombreDisques = 3;
System.out.printf("Résolution des Tours de Hanoï avec %d disques:%n", nombreDisques);
deplacerDisques(nombreDisques, 'A', 'C', 'B');
System.out.printf("Résolu en %d étapes%n", compteurEtapes);
}
}
Visualisation de la pile d’appels¶
Dans IntelliJ, vous pouvez voir la pile d’appels de plusieurs façons :
-
Vue Frames (Cadres)
-
Vue Variables
- Montre les valeurs des paramètres à chaque niveau
- Permet de voir comment les variables changent
-
Vue Debugger
- Affiche la pile complète des appels
- Montre la progression de la récursion
Conseils pour le débogage récursif¶
-
Points d’arrêt conditionnels
-
Logging des appels
public static long fibonacci(int n, int niveau) { String indentation = " ".repeat(niveau); System.out.println(indentation + "Entrée: F(" + n + ")"); if (n <= 1) { System.out.println(indentation + "Retour cas de base: " + n); return n; } long resultat = fibonacci(n - 1, niveau + 1) + fibonacci(n - 2, niveau + 1); System.out.println(indentation + "Retour F(" + n + ") = " + resultat); return resultat; } -
Utilisation de la vue “Evaluate Expression”
- Permet d’évaluer des expressions pendant le débogage
- Utile pour vérifier des valeurs intermédiaires
La récursivité peut être difficile à visualiser mentalement, mais le débogueur d’IntelliJ offre des outils puissants pour comprendre comment les appels s’empilent et se résolvent.
Utilisation de l’IA
Page rédigée en partie avec l’aide d’un assistant IA. L’IA a été utilisée pour générer des explications, des exemples et/ou des suggestions de structure. Toutes les informations ont été vérifiées, éditées et complétées par l’auteur.