在定向树的广度第一搜索中跟踪深度。

问题描述 投票:0回答:2

我试图找到根和被遍历的节点的深度之间的距离,例如,如果我有一个下面的附属列表,代表树 { 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
2个回答
1
投票

与其只对节点进行排队,不如将节点和它们的级别作为图元组进行排队,当你查询一个节点时,它总是与当前级别加一,所以当你去查询一个节点并将该节点追加为 visit_order 你还可以从元组中得到节点的级别。

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]

-1
投票

你可以使用字典来跟踪当前的深度。

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]
© www.soinside.com 2019 - 2024. All rights reserved.