获取树的路径但是所有叶子都是python中一个路径中的节点

时间:2016-12-01 13:56:01

标签: python depth-first-search tree-traversal

我有以下Node对象

class Node(object):
    def __init__(parent=None, data)
        self.__parent = parent
        self.__data = data
        self.__children = []

   # parent and data properties getters and setters are left out for convinience

   def add_node(self, node):
       node.parent = self
       self.__children.append(node)

所以我有一棵看起来像这样的树

            dummy_root(nodata)
             /         |      \
            A          B       C              
          /   \      /   \   /   \
         D     E    F    G   H    I 
        / \   / \  / \  / \ / \  / \
       K   L M  N O  P Q  R S  T U  V

我想获得dummy_root所有孩子的所有路径。尚未弄清楚的棘手部分是叶子节点需要属于一条路径,例如

paths = [
            [A, D, K, L], 
            [A, E, M, N], 
            [B, F, O, P], 
            [B, G, Q, R],
            [C, H, S, T], 
            [C, I, U, V]
]

我找到了一种获取所有路径的方法,但我得到的是每个叶子的不同路径,例如

[A, D, K] and [A, D, L]

Python代码:

 def __find_paths_recursive(node, path):
    path = deepcopy(path)
    path.append(node.data)
    if not node.children:
        pathss.append(path)
    for child in node.children:
        self.__find_paths_recursive(child, path)

for child in dummy_root.children:
    path = []
    find_paths_recursive(child, path)

2 个答案:

答案 0 :(得分:1)

您可以使用groupby

在结果paths上添加一次迭代
result = []
for prefix, paths_iter in groupby(paths, key=lambda x: x[:-1]):
    result.append(prefix + [lst[-1] for lst in val])

print(result)
[[A, D, K, L],
 [A, E, M, N], 
 [B, F, O, P], 
 [B, G, Q, R],
 [C, H, S, T], 
 [C, I, U, V]]

另一种方法是在节点处理期间检查子节点是否为叶子:

def __find_paths_recursive(node, path):
    path = deepcopy(path)
    path.append(node.data)
    if not node.children:
        return
    if node.children[0].children:  # children are not leafs
        for child in node.children:
            self.__find_paths_recursive(child, path)
    else:
        path.extend(node.children)  # since all children are leafs
        paths.append(path)

答案 1 :(得分:0)

我仍然不确定我是否正确得到这个,如果不让我知道

[A,D,K][A,D,L]转到[A,D,K,L], 你可以将它们变成OrderedSets并获得union

每次处理完叶节点时都可以添加此步骤。

或者,您可以为根节点的每个孩子执行preorder traversal