给定一个类似 'tree' 的数据结构,打印出从叶节点到根节点的所有路径

Given a 'tree' like data structure, print out all the paths from leaf to root

请有人指导我正确的方向,我不明白如何return从叶到根的结果

tree = {
    "name": "root",
    "children": [
        {
            "name": "child1",
            "children": [
                {
                    "name": "grand_child1",
                    "children": []
                },
                {
                    "name": "grand_child2",
                    "children": []
                }
            ]
        },
        {
            "name": "child2",
            "children": []
        }
    ]
}

编辑: 解决方案应该是一种算法,因为如果树深度增加它应该仍然有效

def get_paths(hash)
  # Stop method and return name if name is address
  return hash[:name] if hash[:children].empty?
  paths = [] # Declaring path variable
  # Inspecting children
  hash[:children].each do |child|
    child_paths = get_paths(child)
    if child_paths.is_a? String
      paths << [child_paths, hash[:name]]
    else
      child_paths.each { |path| path << hash[:name] }
      paths += child_paths
    end
  end
  paths # Return paths
end

p *get_paths(tree).map { |path| path.to_s[1..-2] }
# => "grand_child1", "child1,", "root"
# => "grand_child2", "child1,", "root"
# => "child2", "root"

您可以使用递归,例如:

def traverse(node, *names, &block)
  names.unshift(node[:name])

  yield *names and return if node[:children].empty?

  node[:children].each { |child| traverse(child, *names, &block) }
end

该方法在单个节点上运行。在每次调用时,它将节点的名称添加到收集的 names 列表(最初为空)。然后它为每个 child 再次调用自己,传递 names。如果一个节点没有任何 children,它会产生 names 到给定的块。 (这也被传递了)

用法:

traverse(tree) do |*names|
  p name: names
end

输出:

{:name=>["grand_child1", "child1", "root"]}
{:name=>["grand_child2", "child1", "root"]}
{:name=>["child2", "root"]}
def explore_tree(tree, names=[])
  names = [tree[:name]] + names
  if tree[:children].empty?
    p names
  else
    tree[:children].each { |child| explore_tree(child, names) }
  end
end
explore_tree(tree)

显示

["grand_child1", "child1", "root"]
["grand_child2", "child1", "root"]
["child2", "root"]