邻接链表循环检测 - Java

时间:2015-01-06 04:45:46

标签: java cycle directed-graph adjacency-list cycle-detection

如果我的邻接列表有一个周期,我有一些问题。 我想创建一个函数来检查我的邻接列表是否现有至少一个周期

根据我的计划。首先,我必须输入根节点,然后输入许多节点,图中的节点,边数和表示边的邻接列表。邻接列表中的每个条目都包含一对节点。

示例输入:

Root node: "A"
Number of nodes: 3
Vertices/Nodes:
A
B
C
Number of edges: 3
A
B
B
C
C
A

A --> B
B --> C
C --> A

上面的样本输入有一个周期:[ A - > B - > C - > A ] 我想输出是否有周期。

到目前为止,这是我的计划:

import java.util.Scanner;

class Neighbor {
public int vertexNum;
public Neighbor next;
public Neighbor(int vnum, Neighbor nbr) {
        this.vertexNum = vnum;
        next = nbr;
    }
}

class Vertex {
String name;
Neighbor adjList;
Vertex(String name, Neighbor neighbors) {
        this.name = name;
        this.adjList = neighbors;
    }
}

public class DirectedCycle {

Vertex[] adjLists;

public DirectedCycle() {

    Scanner sc = new Scanner(System.in);
    //Root Node
    System.out.print("Root node: ");
    String rn = sc.nextLine();

    //Number of nodes
    System.out.print("Number of vertices/nodes: ");
    int nodes = sc.nextInt();
    adjLists = new Vertex[nodes];

    //List of nodes
    System.out.println("Vertices:");
    for (int v=0; v < adjLists.length; v++) {
        String letter = sc.next();
        adjLists[v] = new Vertex(letter, null);
    }
    //Number of edges
    System.out.print("Number of edges: ");
    int edges = sc.nextInt();
    System.out.println("<v1> <v2>");
    for(int i=0; i<edges; i++) {

        int v1 = indexForName(sc.next());
        int v2 = indexForName(sc.next());

        adjLists[v1].adjList = new Neighbor(v2, adjLists[v1].adjList);
    }
}

int indexForName(String name) {
    for (int v=0; v < adjLists.length; v++) {
        if (adjLists[v].name.equals(name)) {
            return v;
        }
    }
    return -1;
}   

public void print() {

    System.out.println();
    for (int v=0; v < adjLists.length; v++) {
        System.out.print(adjLists[v].name);
        for (Neighbor nbr=adjLists[v].adjList; nbr != null; nbr=nbr.next) {
            String name = adjLists[nbr.vertexNum].name;
            System.out.print(" --> " + name);
        }
        System.out.println("\n");
    }
}

public static void main(String[] args)  {
    DirectedCycle graph = new DirectedCycle();
    graph.print();
    }
}

我上面的程序还没有一个检查周期的功能,而且我想实现根节点的事情 ..如果有人可以改进我的程序,只需回答我并给我一些代码我可以依靠。谢谢! (我是初学者!)

2 个答案:

答案 0 :(得分:2)

Floyd's Cycle detection algo.中检测循环的最有效方法,它基本上是在链表上移动两个指针,一个一步一步正常移动一步慢指针而另一个以慢速两倍速度移动指针,即快速指针。

相同的Java代码。

&#13;
&#13;
boolean detectloop(Node list) {
    if(list == null) 
        return false;
    Node slow, fast; 
    slow = fast = list; 
    while(true) {
        slow = slow.next;          
        if(fast.next != null)
            fast = fast.next.next; 
        else
            return false;
        if(slow == null || fast == null) 
            return false;
        if(slow == fast)
            return true;
    }
}
&#13;
&#13;
&#13;

答案 1 :(得分:1)

要检查链接列表的循环,您希望使用两个不同的指针进行迭代,其中一个指针在列表中移动两倍。如果存在循环,则最终将使用此方法检测。此外,对于结束条件,您可以检查是否已访问所有节点,如果是,则没有循环。