给定一个类似 '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"]
请有人指导我正确的方向,我不明白如何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"]