【问题标题】:Why do I need the visited state in Breadth First Search?为什么在广度优先搜索中需要访问状态?
【发布时间】:2014-10-19 13:33:08
【问题描述】:

我已经实现了广度优先搜索算法(实际上,它是广度优先遍历,因为我没有搜索任何特定节点,只是按照访问顺序打印出节点值)并且没有使用任何状态跟踪每个节点 - 即我没有将任何节点标记为已访问。在大多数 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;
        }
    }
}

【问题讨论】:

    标签: algorithm


    【解决方案1】:

    您见过的大多数 BFS 实现都会遍历任意图并遍历树。这两种情况的区别在于循环。任意图可以拥有它们,并且状态对于不将节点两次放入队列是必要的,但在您的情况下,您可能没有它们。

    【讨论】:

      【解决方案2】:

      您的代码引用了一棵树。根据定义,一棵树不能有环,所以你是对的,如果你正在遍历一棵树,你不需要跟踪顶点是否被访问过。一个图可以有循环,因此它可以使多个顶点成为一个顶点的合法父节点。

      例如,具有四个顶点(A、B、C、D)的图和以下拓扑:

       A
      / \
      B C
      \ /
       D
      

      如果从A开始进行广度优先搜索,B&C都可以到达D。在执行过程中,B&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);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-09-21
        • 2010-12-12
        • 1970-01-01
        • 2011-01-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多