2017-06-04 2 views
0

Je suis actuellement en train d'essayer de représenter graphiquement un jeu en créant la classe graphique par moi-même. Le constructeur est celui-ci (l'espoir Je n'ai aucune erreur logique ici):java.lang.StackOverflowError dû à l'itérateur dans DFS

private int nNodes; 
    private int nEdges; 
    private List<Integer> adj[]; 
    private boolean visited[]; 

    public GameGraph() 
    { 
     nNodes = 81; 
     adj = new LinkedList[nNodes]; 
     for(int i = 0; i < nNodes; i++) 
      adj[i] = new LinkedList(); 
     visited = new boolean[nNodes]; 
    } 

Je vérifie s'il y a un chemin entre une source et la destination en utilisant la profondeur premier algorithme de recherche. C'est ce que je l'ai écrit:

public boolean hasPath(int source , int dest) 
     { 
      if(source >= nNodes) 
       return false; 
      else 
      { 
       visited[source] = true; 

       try 
       { 
        Iterator<Integer> iterator = adj[source].listIterator(); 
        while(iterator.hasNext()) 
        { 
         int n = iterator.next(); 
         if(n == dest) 
          return true; 
         visited[n] = true; 
         if(hasPath(n, dest)) 
          return true; 
        }//end while 
        return false; 
       }//end try 
       catch(NullPointerException exception) 
       { 
        exception.printStackTrace(); 
       }//end catch 

       return false; 
      }//end else 
     }//end method has path 

Le problème est que lorsque je lance cette méthode dans une classe principale, j'ai cette erreur:

Exception in thread "main" java.lang.StackOverflowError 
    at java.util.LinkedList$ListItr.<init>(Unknown Source) 
    at java.util.LinkedList.listIterator(Unknown Source) 
    at java.util.AbstractList.listIterator(Unknown Source) 
    at java.util.AbstractSequentialList.iterator(Unknown Source) 
    at logic.GameGraph.hasPath(GameGraph.java:67) 
    at logic.GameGraph.hasPath(GameGraph.java:74)at logic.GameGraph.hasPath(GameGraph.java:74) 
    at logic.GameGraph.hasPath(GameGraph.java:74) 
    at logic.GameGraph.hasPath(GameGraph.java:74) 

ligne 67 est la suivante:

Iterator<Integer> iterator = adj[source].listIterator(); 

Et la ligne 74 est l'appel récursif:

if(hasPath(n, dest)) 

Je lis à propos de StackOverflowError et cela a quelque chose à voir avec le manque de mémoire disponible, je comprends que celui-là et ma question n'est pas ça. Mais je ne comprends pas pourquoi cela devrait se produire ici cause de l'itérateur. Je l'ai essayé même avec des nœuds proches les uns des autres qui ne font que quelques appels récursifs, et la même erreur se produit.

+1

Vous ne jamais vérifier si oui ou non vous avez alraedy visité le nœud. Vous le marquez seulement comme viisited, mais quand vous le rencontrez encore vous le vérifiez encore => récursion infinie. – Polygnome

+0

Ajoutez une instruction 'println()' au début de la méthode 'hasPath()', en imprimant les deux paramètres. La sortie aidera à identifier pourquoi votre code échoue. Ceci est appelé ** débogage **. Vous pouvez également lire "[Qu'est-ce qu'un débogueur et comment peut-il m'aider à diagnostiquer des problèmes?]" (Https://stackoverflow.com/q/25385173/5221149) ", bien qu'une simple déclaration" print "soit probablement la plus facile façon de voir le problème. – Andreas

+0

@Polygnome oui vous avez raison, merci –

Répondre

1

Avant d'entrer dans l'enregistrement d'appel récursif si vous avez déjà couvert ce nœud à l'aide

.... 
int n = iterator.next(); 
if(!visited[n]){ 
... 
} 
+0

merci, je l'ai remarqué trop tard –