6
votes

Comment obtenir tous les enfants d'un parent, puis de leurs enfants à l'aide de la récursivité

Salutations:

J'ai la métaphore des transactions parent dans mon application Web JSP. J'ai une carte d'identité de transaction dans une base de données et que l'exigence est d'afficher tous les enfants du parent, puis des enfants ultérieurs des enfants du parent. En réalité, cette liste des parents et de leurs enfants ne seront jamais plus de 4 ou 5 niveaux de profondeur, mais je dois prendre en compte qu'il peut aller plus de couches que cela.

J'ai essayé de le faire, cela va récursion comme suit: xxx

ceci ne fonctionne pas, génère un débordement de pile comme la boucle passe. Des idées sur la meilleure façon de faire cela?


3 commentaires

@Jseals: sur Stackoverflow Vous pouvez marquer du texte sous forme de code en le sélectionnant et en appuyant sur Ctrl + K au lieu d'utiliser (je l'ai fait pour cette question)


Je ne vois aucune vraie récursive dans le code donné. Vous êtes peut-être trop dépassé de cela. Il existe des moyens de récursion profonde si le résultat final dépend du résultat de la méthode récursive, mais la méthode est déjà déclarée vide ...


Peter: Merci pour le conseil sur la surbrillance.


5 Réponses :


0
votes

S'il y a un débordement de pile qui se produit, votre récursivité est trop profonde. Vous devrez réécrire l'algorithme comme une itérative (c'est-à-dire à l'aide d'une boucle pour / tandis / foreach).


1 commentaires

Le débordement de la pile est probablement un effet secondaire d'une erreur logique (Récursion infinie), qui ne résulte pas des données ou de la méthode de travertielle.



9
votes

Il y a des moyens de récursion profonde (avec des risques pour obtenir la pile pour faire sauter) si l'argument de la méthode n'est pas immédiatement résolue. C'est à dire. Le résultat final de la méthode appelée dépend du résultat de la méthode elle-même. Pseudo: xxx

Ceci fait attendre le code avec update () jusqu'à ce que le résultat soit connu et qu'il soit donc conservé sur la pile. Et il s'accumule avec chaque invocation de méthode.

Vous pouvez l'optimiser pour utiliser Récuission queue à la place d'un objet de résultat mutable comme argument: xxx

de cette façon, la mise à jour () peut être exécutée immédiatement car l'argument est immédiatement résolue. Tant qu'il n'y ait aucune valeur de retour ou aucune autre logique pour arriver après l'appel à processus () , l'exécution peut l'optimiser en supprimant l'appel de la pile. Voir également l'article Wiki AforLinked sur la récursion de la queue et Ce site .

Cependant .. Le code que vous avez posté semble être déjà récursif de la queue. Donc, le problème se trouve ailleurs. Après avoir étudié votre code, on dirait que vous êtes itération sur les enfants mêmes à chaque fois. C'est à dire. Il y a juste un moyen d'une boucle infinie. Probablement le si vérifie est faux et / ou les enfants ont une bronde de retour dans son propre arbre parent-enfant.


0 commentaires

4
votes

Je suppose que vous avez une boucle infinie ...

  1. Childlist avoir le même parent
  2. alltremortransactionsvo est par définition l'un des éléments de Childlist
  3. -> Lorsque vous recursez, vous construisez à nouveau le même Childlist et choisissez le premier AllTremorTransactionsvo comme avant

    Je construis habituellement un tel code récursif comme celui-ci: xxx


0 commentaires

1
votes

Je rencontrais le même problème récemment (en utilisant trop de pile) et utilisé un algorithme itératif. L'exemple est en JavaScript, mais peut être facilement adapté: xxx


1 commentaires

Cela va pas récupérer tous les éléments, il ne récupérera que les éléments de la première dimension.



0
votes

J'ai pu résoudre ma condition Stackoverflow comme suit:

private static void processChildrenTransactions(AllTremorTransactionsVO parentBean, ArrayList<AllTremorTransactionsVO> childCandidatesList ) {
    ArrayList<AllTremorTransactionsVO> childList = new ArrayList<AllTremorTransactionsVO>();
    ArrayList<AllTremorTransactionsVO> childListTwo = new ArrayList<AllTremorTransactionsVO>();

    for (AllTremorTransactionsVO childTransactions : childCandidatesList) {
        childListTwo.add(childTransactions);
        if (childTransactions.getParentGuid() != null) {
            //gets a list of every trans with a child
            if (childTransactions.getParentGuid().equalsIgnoreCase(parentBean.getTransactionGuid())){
                childList.add(childTransactions);
                childListTwo.remove(childTransactions);
            }
        }
    }

    parentBean.setChildTransactions(childList);

    for (AllTremorTransactionsVO allTremorTransactionsVO : childList) {
        processChildrenTransactions(allTremorTransactionsVO, childListTwo);
        //processChildrenTransactions(allTremorTransactionsVO, childList);
    }

    return;

}


0 commentaires