
// Klasse AbstractGraph

   /**
    * Gibt alle Wege bzw. Bahnen von einem bestimmten Knoten
    * zu einem bestimmten Knoten auf System.out aus.
    *
    * @param  fromVertex der Startknoten.
    * @param  toVertex   der Endknoten.
    *
    * @throws IndexOutOfBoundsException falls fromVertex oder toVertex auerhalb des zulssigen Bereichs liegt
    *                                   (0 .. getNumberOfVertices()-1).
    */
   public void printAllPaths(int fromVertex, int toVertex) {
      boolean[] visited = new boolean[this.getNumberOfVertices()];
      java.util.Stack<java.util.Iterator<Graph.Edge>> itStack = new java.util.Stack<java.util.Iterator<Graph.Edge>>();
      java.util.Stack<Integer> nodeStack = new java.util.Stack<Integer>();
      System.out.println("Alle " + (this.directed() ? "Bahnen" : "Wege") + " von " +
                         this.getVertexLabel(fromVertex) + "[" + fromVertex + "] zu " +
                         this.getVertexLabel(toVertex) + "[" + toVertex + "]:");
      if (fromVertex == toVertex) { System.out.println("Start- und Zielknoten sind gleich."); return; }
      visited[fromVertex] = true;
      itStack.push(this.edgeIterator(fromVertex));
      nodeStack.push(fromVertex);
      do {
         if (itStack.peek().hasNext()) {
            Graph.Edge currentEdge = itStack.peek().next();
            int toVert = currentEdge.getToVertex();
            if (toVert == toVertex) {
               for(int i : nodeStack) System.out.print(getVertexLabel(i) + "[" + i + "] -> ");
               System.out.println(getVertexLabel(toVert) + "[" + toVert + "]");
            } else if (!visited[toVert]) {
               visited[toVert] = true;
               itStack.push(this.edgeIterator(toVert));
               nodeStack.push(toVert);
            }
         } else {
            itStack.pop();
            visited[nodeStack.pop()] = false;
         }
      } while(!itStack.isEmpty());
   }

   /**
    * Liefert die sssp-Vorgngerknoten. Verwendet dazu den Algorithmus von Dijkstra.
    * (was passiert bei negativen Kantengewichten?)
    *
    * @param startVertex der Index des Startknotens.
    *
    * @return ein Feld der Vorgngerknoten in einem krzesten Pfad
    *         vom Startknoten zum jeweiligen Knoten.
    *
    * @throws IndexOutOfBoundsException falls startVertex auerhalb des zulssigen Bereichs liegt
    *                                   (0 .. getNumberOfVertices()-1).
    */
   public int[] ssspPath(int startVertex) {
      double[] distance = new double[this.getNumberOfVertices()];
      boolean[] visited = new boolean[this.getNumberOfVertices()];
      int[] parent      = new int[this.getNumberOfVertices()];
      for (int i = 0; i < parent.length; ++i) parent[i] = -1;
      visited[startVertex] = true;
      for (int i = 0; i < distance.length; ++i) distance[i] = Double.POSITIVE_INFINITY;
      for (java.util.Iterator<Graph.Edge> it = this.edgeIterator(startVertex); it.hasNext(); ) {
         Graph.Edge edge = it.next();
         distance[edge.getToVertex()] = edge.getWeight();
         parent  [edge.getToVertex()] = startVertex;
      }
      distance[startVertex] =  0;
      parent[startVertex]   = -2;
      for (int wh = 0; wh < this.getNumberOfVertices() - 1; ++wh) {
         double minWeight = Double.POSITIVE_INFINITY;
         int minVertex = -1;
         for (int i = 0; i < this.getNumberOfVertices(); i++) {
            if ((!visited[i]) && minWeight >= distance[i]) {
               minWeight = distance[i];
               minVertex = i;
            }
         }
         if (distance[minVertex] == Double.POSITIVE_INFINITY) return parent;
         visited[minVertex] = true;
         for (java.util.Iterator<Graph.Edge> it = this.edgeIterator(minVertex); it.hasNext(); ) {
            Graph.Edge edge = it.next();
            if (distance[edge.getToVertex()] > distance[minVertex] + edge.getWeight()) {
                distance[edge.getToVertex()] = distance[minVertex] + edge.getWeight();
                parent  [edge.getToVertex()] = minVertex;
            }
         }
      }
      return parent;
   }

