Quellcode
- import java.util.*;
- import fhw.ADSTool;
- /**
- * A1: Topologisches Sortieren
- * @author Torben Brodt & Marco May
- *
- */
- public class A1 {
- enum Status {start, stop};
- /**
- * Mainmethode
- * @param args-Kommandozeilenparameter
- */
- public static void main(String[] args) {
- Graph g = new Graph();
- String[] zahlen = ADSTool.readStringArray(args.length == 0 ? "u12a1simple.dat" : args[0]);
- for (int i = 0; i < zahlen.length - 1; i += 2) {
- if (!g.containsNode(zahlen[i]))
- g.addNode(zahlen[i]);
- if (!g.containsNode(zahlen[i + 1]))
- g.addNode(zahlen[i + 1]);
- if (!g.containsEdge(zahlen[i], zahlen[i + 1]))
- g.addEdge(zahlen[i], zahlen[i + 1]);
- }
- //g.show();
- List<String> llist = new LinkedList<String>();
- if (acyclic(g, llist)){ //Graph ist nicht zyklisch und f�llt Liste
- if (check(zahlen, llist)) { //wenn Liste identisch mit Vorgabe
- for (ListIterator it = llist.listIterator(); it.hasNext();)
- System.out.print(it.next()+" < ");
- }
- }
- else //Graph ist zyklisch
- System.out.println("Zyklus");
- }
- /**
- * Test den Graphen auf einen Zyklus (aus der Vorlesung)
- * @param g -Der Graph
- * @param llist-Liste
- */
- static boolean acyclic(Graph g, List<String> llist) {
- Map<String, Status> visited = new TreeMap<String, Status>();
- for (Iterator<String> it = g.nodeIterator(); it.hasNext();) {
- String n = it.next();
- if (!visited.containsKey(n))
- if (!acyclicRek(g, n, visited, llist))
- return false;
- }
- return true;
- }
- /**
- * Prueft ob unsere Liste richtig ist
- * @param objects - Zu pruefende Objekte
- * @param llist -Liste, die wir erstellt haben
- * @return true, gdw. Check erfolgreich war
- */
- static boolean check(String[] objects, List<String> llist) {
- for(int i=0; i<objects.length-1; i+=2) {
- String left = objects[i];
- String right = objects[i+1];
- boolean oK = false;
- boolean leftNumberFound = false; //Bevor man die Liste durchgeht
- //9 & 2 sollen gefunden werden
- for (ListIterator<String> it = llist.listIterator(); it.hasNext();){
- String suche = it.next();
- if(suche.equals(left)) {
- //Suche erst nach der linken Zahl
- //9 gefunden. Suche rechts davon nach 2
- leftNumberFound = true; //Linke Zahl gefunden
- }
- if(leftNumberFound == true && suche.equals(right)) {
- // Wenn die linke Zahl schon gefunden wurde,
- // dann suche nach der rechten Zahl
- // 2 rechts davon gefunden - alles i.O.
- oK = true; // In diesem Durchlauf ist also alles OK
- break;
- }
- }
- if(oK == false)
- return false;
- }
- return true;
- }
- /**
- * Rekursive Hilfsfunktion fuer acyclic()
- * @param g - zu pruefender Graph
- * @param node -aktueller Knoten
- * @param visited -Besuchte Objekte
- * @param llist -Liste der Zahlen
- * @return true, gdw. Rek. erfolgreich
- */
- @SuppressWarnings("unchecked")
- static boolean acyclicRek(Graph g, String node, Map<String, Status> visited, List<String> llist) {
- visited.put(node, Status.start); // Start Knoten expandieren
- for (Iterator<String> it = g.edgeIterator(node); it.hasNext();) {
- String expanded = it.next();
- if (visited.containsKey(expanded)) {
- if (visited.get(expanded).equals(Status.start)) // Back-Edge,
- // Zyklus
- return false; // else Cross-Edge, ok
- } else { // !visited.containsKey(expanded)
- visited.put(expanded, Status.start);
- if (!acyclicRek(g, expanded, visited, llist)) // rekursiv Zyklus
- // erkannt
- return false;
- }
- }
- visited.put(node, Status.stop); // Stop Knoten expandieren
- llist.add(0,node);
- return true;
- }
- }