2

隣接リストにサイクルがあるかどうかを確認する際に問題があります。隣接リストに少なくとも 1 つのサイクルが存在するかどうかをチェックする関数を作成したいと考えています。

私のプログラムに基づいています。まず、ルート ノードを入力する必要があります。続いて、ノードの数、グラフ内のノード、エッジの数、およびエッジを表す隣接リストを入力します。隣接リストの各エントリには、ノードのペアが含まれています。

サンプル入力:

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();
    }
}

上記の私のプログラムには、サイクルをチェックする関数がまだありません。また、ルートノードのことを実装したい..誰かが上記の私のプログラムを改善できる場合は、私に答えて、信頼できるコードを教えてください. ありがとう!(初心者です!)

4

2 に答える 2

3

フロイドの周期検出アルゴリズムで周期を検出する最も効率的な方法。これは基本的に、リンクされたリスト上で 2 つのポインターを移動します。1 つは通常の 1 ステップずつ低速ポインターで移動し、もう 1 つは低速ポインターの 2 倍の速度で移動します。つまり、高速ポインターです。

同じためのJavaコード。

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;
    }
}

于 2015-01-06T05:10:51.087 に答える