我编写了以下代码,使用深度优先搜索遍历以上图形,我得到的输出为0 1 3 6 4 5 2。
我想使用DFS检查是否正确的遍历,如果不是,什么是正确的遍历。另外,我需要在代码中进行哪些更改才能带来正确的输出。
byte b = 0b111;
邻接指标
public void DFSTraversal()
{
int v;
int vFirst = 0;
Stack<Integer> st = new Stack<Integer>();
Boolean[] visited = new Boolean[vert];
for(int j = 0 ; j < vert ; j++ )
{
visited[j] = false;
}
// st is a stack
st.push(vFirst);
while(!st.isEmpty())
{
v = st.peek();
if(!visited[v])
{
System.out.printf("%d " , +v);
visited[v]=true;
}
for (int i = 0; i < vert; i++)
{
if ((matrix[v][i] == 1) && (!visited[i]))
{
st.push(i);
visited[i] = true;
System.out.printf("%d ", +i);
v = i;
}
}
st.pop();
}
答案 0 :(得分:0)
从图片中,假设顶点的边缘按其指向的节点的顺序递增,则正确的输出为:0 1 3 6 2 4 5。
您遇到的问题是,您已经将动态编程方法与堆栈混合在一起,并将迭代方法与重写for
遍历所有顶点进行了混合。如果一个顶点与另一个索引的边比其自身索引的边低,则它不会立即访问该节点,而是求助于堆栈。具有未访问边缘的第一边缘的最后一个顶点。
您可以通过仅使用动态编程方法来解决此问题,然后通过边缘向后循环,如果不使用它们,则将其推入堆栈。这样会将边缘留在堆栈顶部的最低值顶点上,以备下次迭代时使用。
您的深度优先搜索循环将变为:
while (!st.isEmpty()) {
int vertex = st.pop();
if (!visited[vertex]) {
System.out.printf("%d ", vertex);
visited[vertex] = true;
for (int i = numVertices - 1; i >= 0; --i) {
if (edges[vertex][i] == 1 && !visited[i]) {
st.push(i);
}
}
}
}
这样,您仅使用单个循环(您的while
循环),该循环不断从堆栈中弹出。访问顶点时,它将所有未访问的顶点和已连接的顶点以相反的顺序推入堆栈。这意味着顶点的编号最小的子代是下一个要访问的子代(DFS)。如果顶点被访问并且位于堆栈的更深处,则再次访问该顶点时会被忽略,其子顶点也将被忽略(它们也已经被访问过)。
然后可以通过将堆栈放入队列并按递增顺序添加顶点,将其更改为“面包优先搜索”。
答案 1 :(得分:-1)
public void DFSTraversal() {
int v;
int vFirst = 0;
Stack<Integer> st = new Stack<Integer>();
Boolean[] visited = new Boolean[vert];
for (int j = 0; j < vert; j++) {
visited[j] = false;
}
// st is a stack
st.push(vFirst);
while (!st.isEmpty()) {
v = st.pop();
if (!visited[v]) {
System.out.printf("%d ", +v);
visited[v] = true;
}
for (int i = 0; i < vert; i++) {
if ((matrix[v][i] == 1) && (!visited[i])) {
st.push(i);
}
}
}
}
在从堆栈中弹出元素时,应打印输出。如果在要检查当前节点所有相邻节点的for循环中打印它,它将成为广度优先搜索(BFS)而不是DFS。
编辑:
添加了完整代码。