将树(非二进制)转换为路径列表

时间:2019-03-29 09:34:33

标签: java algorithm

我有一个树实现:

class Node {
    String name;
    List<Node> childs;
}

我需要将其转换为从根到每个叶子的路径列表。

3 个答案:

答案 0 :(得分:2)

我没有能力测试这段代码,但是总体思路是通过子元素上的for-each循环遍历树。通过在每个递归步骤上添加当前名称,我们将当前路径保存在字符串中。然后点击叶子,将当前路径添加到列表中。

public ArrayList<String> buildListOfPaths(Node tree) {
    ArrayList<String> list = new ArrayList<String>();
    String str = "";
    traverse(tree, list, str);
    return list;
}

// The idea on how to iterate the elements comes from:
// https://stackoverflow.com/a/19338057
public void traverse(Node root, ArrayList<String> list, String str){ 
    // we know it's a leaf so we can add this path to the list
    if (root.getChildren() == null) {
        list.add(str + root.name);
        return;
    } else {
        for(Node each : root.getChildren()){
            traverse(each, list, str + each.name);
        }
    }
}

答案 1 :(得分:1)

使用python修改DFS并收集从根到叶的所有路径的示例。代码未经过全面测试。

class Node:
    def __init__(self, index):
        self.index = index
        self.children = []

    def is_leaf(self):
        return len(self.children) == 0

    def __str__(self):
        return str(self.index)


def _remove_node_on_path_until_finding_parent_of_curr_node(curr_node, curr_path):
    while len(curr_path) > 0 and curr_node not in curr_path[-1].children:
        curr_path.pop(-1)


def modified_dfs(root):
    all_paths = []
    stack_node_to_visit = [root]
    curr_path = []
    while len(stack_node_to_visit) > 0:
        node = stack_node_to_visit.pop(-1)
        _remove_node_on_path_until_finding_parent_of_curr_node(node, curr_path)
        curr_path.append(node)
        if node.is_leaf():
            all_paths.append(curr_path.copy())
        else:
            for child in node.children:
                stack_node_to_visit.append(child)
    return all_paths


################# example usage ####################
root = Node(0)
for i in [1, 2, 3]:
    tmp_child = Node(i)
    root.children.append(tmp_child)
    for j in [100, 200, 300, 400]:
        tmp_child.children.append(Node(j + i))

path_list = modified_dfs(root)

for path in path_list:
    index_list = [str(node) for node in path]
    print(','.join(index_list))

基本上,我们会像往常一样执行DFS,但是在从根到叶遍历时会保留curr_path,从而更新curr_path

答案 2 :(得分:1)

您还可以按照以下迭代方法进行操作:

public static List<String> getPaths(Node root) {
    List<String> paths = new LinkedList<>();
    if(root == null)
        return paths;
    Stack<Pair<Node, String>> stack = new Stack<>();
    stack.push(new Pair<>(root, ""));
    while(!stack.isEmpty()) {
        Pair<Node, String> cur = stack.pop();
        Node node = cur.getKey();
        String prefix = cur.getValue() + node.name;
        if(node.childs == null || node.childs.isEmpty())
            paths.add(prefix);
        for(Node child: node.childs)
            stack.push(new Pair<>(child, prefix + "/"));
    }
    return paths;
}