简体   繁体   English

在图遍历中不了解基于DFS的退货顺序

[英]not understanding the return order based on DFS in graph traversal

I'm currently reviewing DFS and BFS in graphs, and came upon this question on code review . 我目前正在查看图形中的DFS和BFS,并在代码审查中遇到了这个问题

Here is the code that is given as the "correct" solution 这是作为“正确”解决方案给出的代码

graph = {'A': set(['B', 'C']),
         'B': set(['A', 'D', 'E']),
         'C': set(['A', 'F']),
         'D': set(['B']),
         'E': set(['B', 'F']),
         'F': set(['C', 'E'])}

def dfs(graph, start):
    visited, stack = set(), [start]
    while stack:
        vertex = stack.pop()
        if vertex not in visited:
            visited.add(vertex)
            stack.extend(graph[vertex] - visited)
    return visited

dfs(graph, 'A') # {'E', 'D', 'F', 'A', 'C', 'B'}

Based on the definition of DFS, how can the solution be in the order of # {'E', 'D', 'F', 'A', 'C', 'B'} ? 根据DFS的定义,解决方案如何按照# {'E', 'D', 'F', 'A', 'C', 'B'}的顺序排列? If I were to traverse from graph A, would the solution not be to go as deep as possible first, and then traverse up? 如果我要从图A遍历,解决方案是不是先尽可能深入,然后向上遍历?

Is this an actual implenentation of DFS, or is it just a "searching algorithm" but is not DFS? 这是DFS的实际体现,还是只是“搜索算法”,而不是DFS?

That is a valid DFS algorithm. 这是有效的DFS算法。 However, because visited is a set, the order of the returned visited nodes will not necessarily be the order that they were inserted. 但是,由于拜访是一个集合,所以返回的visited节点的顺序不一定是它们插入的顺序。 If you want to see the order of insertion, then the following would be more appropriate: 如果要查看插入顺序,则以下更合适:

graph = {'A': set(['B', 'C']),
         'B': set(['A', 'D', 'E']),
         'C': set(['A', 'F']),
         'D': set(['B']),
         'E': set(['B', 'F']),
         'F': set(['C', 'E'])}

def dfs(graph, start):
    visited, stack = [], [start]
    while stack:
        vertex = stack.pop()
        if vertex not in visited:
            visited.append(vertex)
            stack.extend(graph[vertex] - set(visited))
    return visited

print dfs(graph, 'A') # ['A', 'B', 'D', 'E', 'F', 'C']

Also, just a note on the reason why the original author of the code used a set: 另外,请仅注意代码原始作者使用集合的原因:

When you do the vertex not in visited the average amortized cost of using a set is O(1) whereas when using a list is O(n) (see https://wiki.python.org/moin/TimeComplexity ). 当您不vertex not in visited ,使用集合的平均摊销成本为O(1),而使用列表时的平均摊销成本为O(n)(请参阅https://wiki.python.org/moin/TimeComplexity )。 There may also be a significant cost associated with the set(visited) call (although I don't know how significant). set(visited)调用相关的费用也可能很高(尽管我不知道有多重要)。 Either way, this isn't a highly optimized example (and it's in python anyways), and for small graphs no one will care. 无论哪种方式,这都不是一个高度优化的示例(无论如何都在python中),对于小型图,没人会在意。 If you wanted the best of both worlds, you might try maintaining both a list of visited nodes (for the ordering) and a set (for the actual operations), although that then comes at the cost of additional memory use. 如果您希望两全其美,则可以尝试维护访问节点的列表(用于排序)和集合(用于实际操作),尽管这要付出额外的内存使用成本。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM