【问题标题】:Tracking depth in a breadth first search of a directed tree在有向树的广度优先搜索中跟踪深度
【发布时间】:2018-09-26 08:30:25
【问题描述】:

我正在尝试查找根与正在遍历的节点的深度之间的距离,例如,如果我有一个表示树 { 1: [2, 3], 2: [4], 3: [5]} 的以下邻接列表,则会创建一个如下所示的关联列表[0, 1, 1, 2, 2]表示每个节点的级别。

我有以下代码,但看不到我打算在哪里添加计数功能等,理想情况下这也可以处理交叉和后边缘

def bfs(graph, root):
    seen, queue = set([root]), collections.deque([root])
    visit_order = []
    while queue:
        vertex = queue.popleft()
        visit_order.append(vertex)
        for node in graph[vertex]:
            if node not in seen:
                seen.add(node)
                queue.append(node)

    print(visit_order)

【问题讨论】:

    标签: python tree breadth-first-search


    【解决方案1】:

    您可以将节点及其级别作为元组排队,而不是仅将节点排队,当您将节点排队时,它总是与当前级别加一耦合,因此当您将节点出队并将节点附加到 @ 987654321@你也可以从元组中获取节点的级别:

    import collections
    def bfs(graph, root):
        seen, queue = {root}, collections.deque([(root, 0)])
        visit_order = []
        levels = []
        while queue:
            vertex, level = queue.popleft()
            visit_order.append(vertex)
            levels.append(level)
            for node in graph.get(vertex, []):
                if node not in seen:
                    seen.add(node)
                    queue.append((node, level + 1))
    
        print(visit_order)
        print(levels)
    

    这样:

    bfs({ 1: [2, 3], 2: [4], 3: [5]}, 1)
    

    会输出:

    [1, 2, 3, 4, 5]
    [0, 1, 1, 2, 2]
    

    【讨论】:

    • 谢谢你,我以为我见过类似的实现,但不知道如何实现,如果一切顺利,我将对一些图表进行一些测试并标记为已回答,谢谢!
    【解决方案2】:

    您可以使用字典来跟踪当前深度:

    from collections import deque
    d = {1: [2, 3], 2: [4], 3: [5]}
    def bfs(graph, root = 1):
       queue, seen, depths = deque([root]), [], {root:0}
       while queue:
         val = queue.popleft()
         depths.update({i:depths[val] +1 for i in graph.get(val, [])})
         seen.append(val)
         queue.extend([i for i in graph.get(val, []) if i not in seen])
       yield seen, depths
    
    [(_all, _depths)] = bfs(d)
    print([_depths[i] for i in _all])
    

    输出:

    [0, 1, 1, 2, 2]
    

    但是,当使用class 时,逻辑更简单,因为可以应用深度优先遍历:

    class Tree:
      def __init__(self, _start):
         self.__dict__ = {'head':_start, 'data':[Tree(i) for i in d.get(_start, [])]}
      def __contains__(self, _val):
         if self.head != _val and not self.data:
           return False
         return True if self.head == _val else any(_val in i for i in self.data)
      def get_depth(self, _val):
         if self.head == _val:
           return 0
         return 1+[i for i in self.data if _val in i][0].get_depth(_val)
    
    t = Tree(1)
    print([t.get_depth(i) for i in set([i for a, b in d.items() for i in [a, *b]])])
    

    输出:

    [0, 1, 1, 2, 2]
    

    【讨论】:

      猜你喜欢
      • 2015-09-23
      • 2013-08-02
      • 2011-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多