如果要从给定顶点{0..n-1}
进行DFS / BFS的情况下,图的DFS或BFS遍历的顺序是什么?
以下是图表的一种BFS实现
import java.util.LinkedList;
import java.util.ListIterator;
import java.util.Queue;
public class BreadthFirstSearch {
static class Graph {
int V;
LinkedList[] vertexList;
Graph(int v) {
this.V = v;
vertexList = new LinkedList[v];
for (int i = 0; i < v; i++) {
vertexList[i] = new LinkedList<>();
}
}
}
private void addEdge(Graph graph, int src, int dest) {
graph.vertexList[src].add(dest); // Directed Graph Only
}
private void bfs(Graph graph, int vertex) {
if (vertex > graph.V) {
throw new IllegalArgumentException("Value not defined");
}
boolean visited[] = new boolean[graph.V];
Queue<Integer> queue = new LinkedList<>();
queue.add(vertex);
while (!queue.isEmpty()) {
int a = queue.poll();
if (!visited[a]) {
System.out.print(a + " ");
visited[a] = true;
}
for (Object o : graph.vertexList[a]) {
int n = (int) o;
if (!visited[n]) {
queue.add(n);
}
}
}
}
private void traverseGraphList(Graph G) {
int i = 0;
for (LinkedList list : G.vertexList) {
ListIterator itr = list.listIterator();
System.out.print("src: " + i++ + " ");
while (itr.hasNext()) {
System.out.print(" -> " + itr.next());
}
System.out.println();
}
}
public static void main(String args[]) {
BreadthFirstSearch g = new BreadthFirstSearch();
int n = 8;
Graph graph = new Graph(n);
g.addEdge(graph, 0, 1);
g.addEdge(graph, 0, 2);
g.addEdge(graph, 1, 2);
g.addEdge(graph, 2, 0);
g.addEdge(graph, 2, 3);
g.addEdge(graph, 3, 3);
g.addEdge(graph, 3, 4);
g.addEdge(graph, 5, 4);
g.addEdge(graph, 5, 6);
g.addEdge(graph, 7, 6);
System.out.println("BFS starting from node 2");
g.bfs(graph, 2);
System.out.println();
g.traverseGraphList(graph);
//2 0 3 1 4
}
}
输出为2 0 3 1 4
参考方案
如果要遍历图的所有节点,则应注意,由于存在无法从所选根节点访问的节点,因此在使用单个BFS / DFS时将无法遍历它们。
遍历节点的顺序取决于BFS / DFS的实现。您的情况取决于您将每个节点插入到邻接表的顺序。
如果要遍历整个图,则应维护已访问的节点,然后为每个未访问的节点运行BFS / DFS(例如,使用循环)。特别是,遍历节点的出现顺序再次取决于您将实际循环的项目的顺序。
java:继承 - java有哪些替代继承的方法? java大神给出的解决方案 有效的Java:偏重于继承而不是继承。 (这实际上也来自“四人帮”)。他提出的理由是,如果扩展类未明确设计为继承,则继承会引起很多不正常的副作用。例如,对super.someMethod()的任何调用都可以引导您通过未知代码的意外路径。取而代之的是,持有对本来应该扩展的类的引用,然后委托给它。这是与Eric…
Java:BigInteger,如何通过OutputStream编写它 - java我想将BigInteger写入文件。做这个的最好方式是什么。当然,我想从输入流中读取(使用程序,而不是人工)。我必须使用ObjectOutputStream还是有更好的方法?目的是使用尽可能少的字节。谢谢马丁 参考方案 Java序列化(ObjectOutputStream / ObjectInputStream)是将对象序列化为八位字节序列的一种通用方法。但…
Java DefaultSslContextFactory密钥库动态更新 - java我有一个使用org.restlet.engine.ssl.DefaultSslContextFactory的现有应用程序和一个在服务器启动时加载的密钥库文件。我有另一个应用程序,该应用程序创建必须添加的证书服务器运行时动态地更新到密钥库文件。为此,我在代码中创建了证书和私钥,然后将其写入到目录。该目录由bash脚本监视,该脚本检查是否有新文件,如果出现,它将…
Java:线程池如何将线程映射到可运行对象 - java试图绕过Java并发问题,并且很难理解线程池,线程以及它们正在执行的可运行“任务”之间的关系。如果我创建一个有10个线程的线程池,那么我是否必须将相同的任务传递给池中的每个线程,或者池化的线程实际上只是与任务无关的“工人无人机”可用于执行任何任务?无论哪种方式,Executor / ExecutorService如何将正确的任务分配给正确的线程? 参考方案 …
JAVA:字节码和二进制有什么区别? - javajava字节代码(已编译的语言,也称为目标代码)与机器代码(当前计算机的本机代码)之间有什么区别?我读过一些书,他们将字节码称为二进制指令,但我不知道为什么。 参考方案 字节码是独立于平台的,在Windows中运行的编译器编译的字节码仍将在linux / unix / mac中运行。机器代码是特定于平台的,如果在Windows x86中编译,则它将仅在Win…