简体   繁体   English

我在 Java 中的 BFS 最短路径实现有什么问题

[英]What's wrong in my BFS shortest path implementation in Java

import java.io.*;
import java.util.*;

class Graph
{
    private int V;   // No. of vertices
    private LinkedList<Integer> adj[]; //Adjacency Lists
    private LinkedList<Integer> path[];


    Graph(int v)
    {
        V = v;
        adj = new LinkedList[v];
        for (int i=0; i<v; ++i)
            adj[i] = new LinkedList();
        path = new LinkedList[v];
        for(int i=0;i<v;++i)
            adj[i]=new LinkedList();
    }


    void addEdge(int v,int w)
    {
        adj[v].add(w);
    }

    // prints BFS traversal from a given source s
    void BFS(int s,int d)
    {
        boolean visited[] = new boolean[V];
        LinkedList<Integer> queue = new LinkedList<Integer>();


        visited[s]=true;
        queue.add(s);
        path[s].addLast(s);
        while (queue.size() != 0)
        {

            s = queue.poll();
            //System.out.print(s+" ");


            Iterator<Integer> i = adj[s].listIterator();
            while (i.hasNext())
            {
                int n = i.next();
                if (!visited[n])
                {
                    visited[n] = true;
                    queue.add(n);
                    path[n]=path[s];
                    path[n].addLast(n);
                }
            }
        }

        System.out.print("Following is the path from source to destination\n");
        while(path[d].size()!=0)
        {
            int xyz=path[d].getFirst();
            path[d].poll();
            System.out.print(xyz+" ");
        }
    }

    // Driver method to
    public static void main(String args[])
    {
        Graph g = new Graph(4);

        g.addEdge(0, 1);
        g.addEdge(0, 2);
        g.addEdge(1, 2);
        g.addEdge(2, 0);
        g.addEdge(2, 3);
        g.addEdge(3, 3);

        System.out.println("Following is the desired path\n");

        g.BFS(2,3);
    }
}

I need to get the shortest path between nodes 2 and 3.我需要获得节点 2 和 3 之间的最短路径。

You're attempting to add an element to a linked list that is null.您正试图将一个元素添加到一个为空的链表中。 You need to initialize the linked list at index s before you can add to it.您需要在索引 s 处初始化链表,然后才能添加到它。

path[s] = new LinkedList();
path[s].addLast(s);

Additionally, your code is failing because you don't clone the path array when setting the value of path[n]:此外,您的代码失败是因为您在设置 path[n] 的值时没有克隆路径数组:

path[n]=path[s];

You need to change this to:您需要将其更改为:

path[n]= (LinkedList) path[s].clone();

This way the list for n won't retain a reference to the list of s.这样 n 的列表将不会保留对 s 列表的引用。 Currently, the reference is retained, so that whenever you add something to the list for n, that thing will also be added to s.目前,引用被保留,因此每当您向 n 的列表中添加内容时,该内容也将添加到 s。

As there is no information what exactly isn't behaving as expected, it is a bit difficult to say what the error is.由于没有信息究竟是什么行为不符合预期,因此很难说出错误是什么。 But I see two problems with the code:但是我看到代码有两个问题:

First, you don't initialize the elements of the path .首先,您不初始化path的元素。 Instead, in the constructor you initialize the elements of adj twice.相反,在构造函数中,您将adj的元素初始化两次。 So, you should replace one of the lines that say所以,你应该替换说的行之一

for(int i=0; i<v; ++i)
     adj[i] = new LinkedList();

with

for(int i=0; i<v; ++i)
     path[i] = new LinkedList();

or you can just delete the two lines as you will see now:或者您可以删除这两行,就像您现在看到的那样:

The second problem is that you set the different elements of path as the reference to another LinkedList and edit it:第二个问题是你将path的不同元素设置为对另一个 LinkedList 的引用并对其进行编辑:

path[n] = path[s];
path[n].addLast(n);

This has as result that every element of path uses the same LinkedList with the same elements.这导致path每个元素都使用具有相同元素的相同 LinkedList。 Instead you should create a new LinkedList containing the same elements:相反,您应该创建一个包含相同元素的新 LinkedList:

path[n] = new LinkedList(path[s]);
path[n].addLast(n);

EDIT: As Soggiorno said in his answer, you must at least initialize path[s] at the beginning of the BFS -method before adding an element to it:编辑:正如 Soggiorno 在他的回答中所说,在向它添加元素之前,您必须至少在BFS方法的开头初始化path[s]

path[s] = new LinkedList();
path[s].addLast(s);

If you do the initialization for all the elements of path this isn't needed, of course.当然,如果您对path所有元素进行初始化,则不需要。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM