Java 在无向图中查找和打印循环

Java 在无向图中查找和打印循环,java,graph-traversal,Java,Graph Traversal,我正在做一个作业,我需要做一个无向图的DFS,然后如果找到一个循环,就打印一个循环。问题是,我能找到的任何查找循环的算法都不会存储循环-它们只是真/假。我当前的代码只适用于某些图形,而不适用于其他图形。例如,它找不到2节点循环4-5、5-4。而且,它只适用于现在应该是无方向的directed 编辑:这不是关于查找和打印周期的其他问题的重复,因为就我所见,没有任何其他问题涉及如何存储和随后打印周期-只是如何查找周期是否存在并返回true/false 编辑:格式化 附件是我的遍历代码和主要方法 -主

我正在做一个作业,我需要做一个无向图的DFS,然后如果找到一个循环,就打印一个循环。问题是,我能找到的任何查找循环的算法都不会存储循环-它们只是真/假。我当前的代码只适用于某些图形,而不适用于其他图形。例如,它找不到2节点循环4-5、5-4。而且,它只适用于现在应该是无方向的directed

编辑:这不是关于查找和打印周期的其他问题的重复,因为就我所见,没有任何其他问题涉及如何存储和随后打印周期-只是如何查找周期是否存在并返回true/false

编辑:格式化

附件是我的遍历代码和主要方法

-主要方法

    public static void main(String args[]) {
//
//        Graph g = new Graph(8);
//
//        g.add(0, 2);
//        g.add(2, 3);
//        g.add(3, 1);
//        g.add(1, 0);
//
//        g.add(4, 5);
//        g.add(5, 6);
//        g.add(6, 7);
//        g.add(7, 4);
//

//        Graph g = new Graph(6);
//
//        g.add(0, 1);
//        g.add(1, 3);
//        g.add(2, 3);
//        g.add(3, 4);
//        g.add(3, 5);
//


//        Graph g = new Graph(7);
//
//        g.add(0, 1);
//        g.add(0, 2);
//        g.add(0, 3);
//        g.add(3, 4);
//        g.add(4, 3);
//        g.add(4, 5);
//        g.add(4, 6);


         Graph g = new Graph(5);


        g.add(0, 1);
        g.add(2, 3);
        g.add(2, 4);
        g.add(3, 4);





        DepthFirstTraversal dfs = new DepthFirstTraversal(g);

        System.out.println("Following is Depth First Traversal");

        dfs.DFS();

        if (!dfs.isCyclic())
            System.out.println("This graph is acyclic");

    }
-图形类

import java.util.LinkedList;


public class Graph {

    //Number of Vertices
    private int vertices;

    //Linked List to hold edges
    private LinkedList<Integer> edges[];


    public Graph(int verticesGiven) {
        this.vertices = verticesGiven;
        this.edges = new LinkedList[vertices];
        fillNodes(edges, vertices);
    }


    private static void fillNodes(LinkedList<Integer> edges[], int 
    vertices) {
        for (int counter = 0; counter < vertices; ++counter) {
            edges[counter] = new LinkedList();
        }
    }


    void add(int x, int y) {
        edges[x].add(y);
    }

    public int getVertices() {
        return vertices;
    }


    public LinkedList<Integer>[] getEdges() {
        return edges;
    }

}
-遍历和循环搜索

import java.util.*;


public class DepthFirstTraversal {

    //Each traversal has a graph
    private Graph graph;

    //Holds the nodes for each cycle
    private List<Integer> cycle = new ArrayList<Integer>();


    public DepthFirstTraversal(Graph graph) {

        this.graph = graph;
    }


    private void DFSRecursive(int current, boolean visited[], 
    LinkedList<Integer> edges[]) {

        // Say you visited current node
        visited[current] = true;

        //Print the current node
        System.out.print(current + " ");

        // Look at all vertices connected to this one
        Iterator<Integer> iterate = edges[current].listIterator();

        //Check to see everything this is connected to
        while (iterate.hasNext()) {

            //Check to see what the next one is
            int connected = iterate.next();

            //check if you've already visited what it's connected to. 
            If you haven't, check that one out.
            if (!visited[connected])

                //Check whatever the current one is connected to
                DFSRecursive(connected, visited, edges);
        }


    }

    public void DFS() {

        //Check to see how many vertices graph has
        int vertices = graph.getVertices();

        //Keeps track of which vertices have already been visited
        boolean visited[] = new boolean[vertices];

        //Visits all of the nodes
        for (int counter = 0; counter < vertices; ++counter)

            //calls recursive method if this node has not been visited
            if (!visited[counter])
                DFSRecursive(counter, visited, graph.getEdges());
    }

    private Boolean isCyclicRecursive(int index, Boolean visited[], int 
    parent, LinkedList<Integer> edges[]) {

        // Mark the current node as visited
        visited[index] = true;

        //Integer to hold what the node is connected to
        Integer connection;

        // Recur for all the vertices adjacent to this vertex
        Iterator<Integer> iterator = edges[index].iterator();

        //Check to see if the current node has a connection
        while (iterator.hasNext()) {

            //Looks at what is connected to it.
            connection = iterator.next();

            //If you haven't visited the connection, look at that. Sets the current as the parent of the connection.
            if (!visited[connection]) {
                cycle.add(index);
                if (isCyclicRecursive(connection, visited, index, 
              graph.getEdges())) {
                    return true;
                } else {
                    Integer item = new Integer(index);
                    cycle.remove(item);
                }
            }

            //Checks to see if the thing it's connected to is its parent (you've completed a cycle)
            else if (connection != parent) {

                //Add parent and connection
                cycle.add(index);
                cycle.add(connection);

                //Only find the things in current cycle
                for (int i = 0; i < cycle.size(); i++) {

                    //Not a true cycle
//                    if (cycle.size() <= 1)
//                        return false;

                    int first = cycle.get(i);
                    int last = cycle.get(cycle.size() - 1);

                    if (first == last) {
                        System.out.print("Cycle Detected: ");
                        for (int j = 0; j < cycle.size(); j++) {
                            System.out.print(cycle.get(j).toString() + " ");
                        }
                        System.out.println();
                        return true;
                    } else {
                        //only prints things actually in this cycle
                        cycle.remove(i);
                        i--;
                    }
                }
                return true;
            }
        }

        return false;
    }

    /**************************************************************/
    /* Method: isCyclic
    /* Purpose: Checks to see if graph is cyclic
    /* Parameters: None
    /* Returns: None
    /**************************************************************/
    public Boolean isCyclic() {

        //Mark all vertices as not visited
        int vertices = graph.getVertices();

        Boolean visited[] = new Boolean[vertices];

        for (int counter = 0; counter < vertices; counter++)
            visited[counter] = false;

        //For every node, check if it is cyclic
        for (int counter = 0; counter < vertices; counter++)

            //Only check for cyclic if this has been visited
            if (!visited[counter])
                if (isCyclicRecursive(counter, visited, -1, graph.getEdges()))
                    return true;

        return false;
    }

}

我的一个问题是,如果你的图是无向的,你如何看待4-5和5-4作为单独的边?对我来说,在一个无向图中,4-5和5-4是同一条边,因此不是一个圈。在有向图上,它们是不同的,因此形成一个循环。另外,图形数组中的所有LinkedList对象都是长度为2的吗?如果您想要无向的,您可以用集合实现替换图中的LinkedList对象,但这需要更改一些逻辑


无论如何,这似乎很有意义:

非常感谢!我打算把它改成一套装置。另外,我对4-5和5-4的理解是错误的,它们不应该被检测为一个循环。