需要一个类似于DFS的图算法

时间:2010-02-24 00:23:47

标签: algorithm graph-theory directed-graph graph-traversal

我很好奇是否有特定的图算法通过选择一个起始节点然后通过DFS进行遍历未加权的非循环有向图。如果遇到具有未搜索的前驱的节点,那么它应该回溯跟踪传入的路径,直到探索了所有要启动的路径。

我找到了wikipedia category for graph algorithms,但这里有一小部分算法,我对大多数算法并不熟悉。

编辑:示例: 给定图{AB,EB,BC,BD},遍历为:{A,B,E,B,C,D}或唯一顺序为{A,B,E,C,D}。 请注意,如果第一个起始节点的所有路径都耗尽,则此算法与BFS或DFS不同,不需要在新的起始节点重新开始。

3 个答案:

答案 0 :(得分:2)

您正在寻找的是拓扑类型。据我所知,没有任何简单的方法可以在没有任何预计算的情况下以拓扑排序的顺序遍历图形。

获得topsort的标准方法是执行标准DFS,然后按访问时间顺序存储受访节点。最后,反转那些节点,瞧,你按照你想要的顺序。

伪代码:

list topsort

procedure dfs(vertex u)
  mark u as visited
  for each edge (u, v)
    if v not visited
      dfs(v)
  add u to the back of topsort

列表topsort将按照您想要的相反顺序包含顶点。只需反转topsort的元素即可纠正。

答案 1 :(得分:2)

在DFS中,您通常根据从u开始的边选择要访问的顶点。您希望首先选择基于结束于u的边缘。为此,您可以获得transpose graph信息,并尝试首先从那里获取顶点。

这将是这样的:

procedure dfs(vertex u)
  mark u as visited
  for each edge (v, u) //found in transpose graph
    if v not visited
      dfs(v)
  for each edge (u, w)
    if v not visited
      dfs(w)

答案 2 :(得分:2)

如果您正在寻找topological sort,您也可以执行此操作,给定adjacency list(或您可以在(u,v)时间预处理的边O(E)列表):

list top_sort( graph in adjacency list )
     parent = new list
     queue = new queue
     for each u in nodes
         parent(u) = number of parents
         if ( parent(u) is 0 ) // nothing points to node i
             queue.enqueue( u )

     while ( queue is not empty )
         u = queue.pop
         add u to visited
         for each edge ( u, v )
             decrement parent(v) // children all have one less parent
             if ( parent(v) is 0 )
                 queue.enqueue( v )

给定adjacency list(或边(u,v)列表),这是O( V + E ),因为每个边被触摸两次 - 一次递增,一次递减,在{{1每个时间。使用普通队列时,队列最多也会处理每个顶点两次 - 这也可以在O(1)中使用标准队列完成。

请注意,这与DFS(至少是直接实现)的不同之处在于它处理森林。

另一个有趣的注意事项是,如果用O(1)替换queue强加某种结构/排序,你实际上可以按某种顺序返回结果。

例如,对于规范类依赖图(如果你使用Y类,你只能使用X类):

priority_queue

你可能会得到,结果:

100:
101: 100
200: 100 101
201: 
202: 201

但是如果你改变它以便你总是想首先采用编号较低的类,你可以很容易地改变它以返回:

100, 201, 101, 202, 200