Maison  >  Article  >  Java  >  Quelles sont les techniques d’optimisation des appels récursifs dans les fonctions Java ?

Quelles sont les techniques d’optimisation des appels récursifs dans les fonctions Java ?

王林
王林original
2024-04-30 14:06:02625parcourir

Techniques d'optimisation des appels récursifs : Élimination de la récursion de queue : convertissez la récursion de queue en boucles pour éliminer le débordement de pile. Itération au lieu de récursion : utilisez des boucles au lieu de la récursion pour économiser le coût des appels de fonction. Mémo : stocke les résultats des calculs précédents pour réduire le nombre d'appels récursifs.

Quelles sont les techniques d’optimisation des appels récursifs dans les fonctions Java ?

Techniques d'optimisation pour les appels récursifs dans les fonctions Java

La récursion est une technique de programmation puissante qui permet aux fonctions de s'appeler elles-mêmes. Cependant, la récursivité peut provoquer un débordement de pile, en particulier lorsque les appels de fonction sont trop profonds ou lorsque l'ensemble de données en cours de traitement est trop volumineux. Afin d'optimiser les appels récursifs, nous pouvons utiliser les techniques suivantes :

1. Élimination de la récursivité de queue

La récursion de queue signifie que la fonction s'appelle elle-même à la dernière étape. La machine virtuelle Java peut optimiser les récursions de queue en les convertissant en boucles, évitant ainsi les débordements de pile.

public static int factorial(int n) {
    if (n == 0) {
        return 1;
    } else {
        return n * factorial(n - 1); // 尾递归调用
    }
}

2. Utilisez l'itération au lieu de la récursion

Dans certains cas, nous pouvons utiliser des boucles explicites au lieu de la récursion. Cela permet d'économiser la surcharge des appels de fonction et d'éviter les débordements de pile.

public static int factorial(int n) {
    int result = 1;
    for (int i = 1; i <= n; i++) {
        result *= i;
    }
    return result;
}

3. Memo

Memo est une technique utilisée pour stocker des résultats précédemment calculés. Lorsque la fonction s'appelle à nouveau, elle vérifie d'abord si le résultat existe dans le mémo. S'il existe, le résultat est renvoyé directement, sinon un appel récursif est effectué.

import java.util.HashMap;
import java.util.Map;

public static int factorial(int n) {
    Map<Integer, Integer> memo = new HashMap<>();
    return factorial(n, memo);
}

private static int factorial(int n, Map<Integer, Integer> memo) {
    if (n == 0) {
        return 1;
    } else if (memo.containsKey(n)) {
        return memo.get(n);
    } else {
        int result = n * factorial(n - 1);
        memo.put(n, result);
        return result;
    }
}

Exemple pratique

Considérons une fonction récursive qui calcule la séquence de Fibonacci :

public static int fibonacci(int n) {
    if (n <= 1) {
        return n;
    } else {
        return fibonacci(n - 1) + fibonacci(n - 2); // 递归调用
    }
}

Pour les grandes valeurs n, cette fonction peut provoquer un débordement de pile. Nous pouvons l'optimiser en utilisant l'élimination de la récursion de la queue :

public static int fibonacci(int n) {
    return fibonacci(n, 0, 1);
}

private static int fibonacci(int n, int prev, int current) {
    if (n == 0) {
        return prev;
    } else if (n == 1) {
        return current;
    } else {
        return fibonacci(n - 1, current, prev + current); // 尾递归调用
    }
}

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn