我已经实现了广度优先搜索算法(实际上,它是广泛的首次遍历,因为我不是在搜索任何特定节点,只是按访问顺序打印出节点值)并且没有使用任何状态跟踪每个节点 - 即我没有将任何节点标记为已访问。在大多数BFS实现中,我看到了将节点标记为已访问的概念,因此您永远不会访问它两次,但在我的实现中,我无法看到任何可能的情况。
有人可以解释为什么访问状态是有用和/或必要的吗?
这是我的实施:
import java.util.LinkedList;
import java.util.Queue;
public class BFS {
public static void printTree(Node root) {
Queue<Node> queue = new LinkedList<Node>();
queue.add(root);
while(queue.isEmpty() == false) {
Node curr = queue.remove();
System.out.println(curr.getValue());
if (curr.getLeft() != null) {
queue.add(curr.getLeft());
}
if (curr.getRight() != null) {
queue.add(curr.getRight());
}
}
}
public static void main(String[] args) {
Node leaf1 = new Node(5);
Node leaf2 = new Node(6);
Node leaf3 = new Node(7);
Node leaf4 = new Node(7);
Node leaf5 = new Node(11);
Node rightRightRoot = new Node(12, leaf4, leaf5);
Node leftRoot = new Node(1, leaf1, leaf2);
Node rightRoot = new Node(9, leaf3, rightRightRoot);
Node root = new Node(4, leftRoot, rightRoot);
printTree(root);
}
static class Node {
private int value;
private Node left, right;
public Node(int value, Node left, Node right) {
this.value = value;
this.left = left;
this.right = right;
}
public Node(int value) {
this.value = value;
}
public int getValue() {
return value;
}
public Node getLeft() {
return left;
}
public Node getRight() {
return right;
}
}
}
答案 0 :(得分:3)
你见过的大多数BFS实现都会遍历任意图形,然后穿过树。这两种情况的区别在于周期。任意图可以有它们,并且状态对于不将节点放入队列两次是必要的,但在你的情况下你可能没有它们。
答案 1 :(得分:0)
您的代码引用了一棵树。根据定义,树不能有循环,因此如果您正在遍历树,则不需要跟踪是否已访问过顶点。图形可以具有循环,因此它使多个顶点成为顶点的合法父项。
例如,使用四个顶点(A,B,C,D)和以下拓扑图:
A
/ \
B C
\ /
D
如果从A开始广度优先搜索,则B&amp; C可以达到D.执行期间,B&amp; C会将D添加到队列中,因此它将被访问并打印两次。
以下代码将打印4次:
Node D = new Node(4);
Node C = new Node(3, D, null);
Node B = new Node(2, null, D);
Node A = new Node(1, B, C);
printTree(A);