【问题标题】:BFS cycle detectionBFS 循环检测
【发布时间】:2017-06-15 15:47:50
【问题描述】:

有人可以提供使用 BFS 在有向/无向图中搜索循环的逐步伪代码吗?

能得到 O(|V|+|E|) 复杂度吗?

到目前为止,我只看到了 DFS 实现。

【问题讨论】:

  • 为什么要使用 BFS ?你一定要吗 ?如果没有,请阅读此内容,您可能更喜欢使用 DFS:stackoverflow.com/questions/2869647/…
  • @kazu 我想看看它是如何实现的,因为我的实现搞砸了。
  • 你只需要知道是否存在循环还是需要提取特定的循环本身?
  • @Codor 只是存在我会尝试提取自己(但如果你也能提供它会很棒)。

标签: graph-algorithm pseudocode breadth-first-search cycle-detection


【解决方案1】:

您可以采用 非递归 DFS 算法来检测无向图中的循环,其中您将节点的堆栈替换为队列以获得 BFS 算法。很简单:

q <- new queue // for DFS you use just a stack
append the start node of n in q
while q is not empty do
    n <- remove first element of q
    if n is visited
        output 'Hurray, I found a cycle'
    mark n as visited
    for each edge (n, m) in E do
        append m to q

由于 BFS 只访问每个节点和每条边一次,因此复杂度为 O(|V|+|E|)。

【讨论】:

  • 什么是非递归 DFS?你能提供伪代码吗?我尝试实施但无法使其发挥作用。
  • 谢谢。我们必须使用队列吗?你是怎么打印的?
  • 是的,对于 BFS,您必须使用队列。注意,这是伪代码。没有打印。输出语句表示算法已达到特殊状态。这可能在实际实现中打印。
  • 我认为行不通。考虑到同一个节点有两条路径的情况。仅仅因为您以前访问过它,并不能使它成为一个循环。 stackoverflow.com/a/2869661/986067
  • @vcovo 是的,你是对的。我会更新我的描述。
【解决方案2】:

我发现 BFS 算法非常适合。 时间复杂度是一样的。

你想要这样的东西(从维基百科编辑):

Cycle-With-Breadth-First-Search(Graph g, Vertex root):

    create empty set S
    create empty queue Q      

    root.parent = null
    Q.enqueueEdges(root)                      

    while Q is not empty:

        current = Q.dequeue()

        for each node n that is adjacent to current:
            if n is not in S:
                add n to S
                n.parent = current
                Q.enqueue(n)
            else  //We found a cycle
                n.parent = current
                return n and current

我只添加了 else 它的循环块用于循环检测,并删除了原始的 if达到目标块用于目标检测。总的来说,它是相同的算法。

要找到确切的周期,您必须找到 n 和 current 的共同祖先。最低的在 O(n) 时间内可用。比周期是已知的。 n 和当前的祖先。 current 和 n 相连。

有关循环和 BFS 的更多信息,请阅读此链接https://stackoverflow.com/a/4464388/6782134

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-13
    • 2011-09-17
    • 2011-01-25
    • 2014-04-12
    • 1970-01-01
    相关资源
    最近更新 更多