如何转换此树结构
[1, [2, [3, 4]], [5, [6, [7], 8]]]
1
2
3
4
5
6
7
8
....进入这个“反向树”结构,它基本上包含从所有叶子节点到1(根)的路径:
[8, [5, [1]], 7, [6, [5, [1]]], 4, [2, [1]], 3, [2, [1]]]
8
5
1
7
6
5
1
4
2
1
3
2
1
结果甚至不必构造成树,正确顺序的四个平面阵列也可以。
看起来Depth-first search可能是一个相关的算法,但我无法理解伪代码(incidentEdges()返回什么?),所以我很困惑。
如果有人可以提供Ruby方法(或者非常容易理解伪代码)来将原始嵌套数组转换为结果数组,我将无限感激。
这不是一个家庭作业,而是因为我学习了太长时间了......我需要这个来按照问题跟踪器中给定问题的正确顺序打印依赖树。
答案 0 :(得分:1)
您可以使用此代码。这不是我最好的代码,但我也在学习ruby:D(这是一个很好的练习)
a = [1, [2, [3, 4]], [5, [6, [7], 8]]]
class Node
attr_reader :value
attr_reader :parent
attr_reader :children
def initialize(value, parent)
@value = value
@parent = parent
@parent.add_child self unless parent == nil
@children = []
end
def add_child(child)
@children << child
end
def print_node(ident)
Range.new(0,ident).each {print ' '}
print @value.to_s
print "\n"
children.each { |child| child.print_node (ident+4) }
end
end
class Tree
def self.from_array(array)
process array, nil
end
def self.process(array, parent)
node = nil
array.each do |array_item|
if array_item.is_a? Numeric
node = Node.new(array_item, parent)
else
process(array_item, node)
end
end
node
end
def self.print_paths_to_root node
if node.children.empty?
puts print_path_to_root(node)
else
node.children.each do |child|
print_paths_to_root child
end
end
end
def self.print_path_to_root node
if node != nil
node.value.to_s + ' ' + print_path_to_root(node.parent)
else
""
end
end
end
puts 'TREE'
root = Tree.from_array a
root.print_node 0
puts "\n\n\n"
puts 'PATH TO ROOT'
Tree.print_paths_to_root root
答案 1 :(得分:1)
更紧凑的代码:
tree = [1, [2, [3, 4]], [5, [6, [7], 8]]]
def find_reverse_leaf_paths(nodes, prefix = [], paths = [])
leafs = []
nodes.each do |node|
if node.is_a?(Numeric)
leafs.push(node)
else
prefix.push(leafs.pop) unless leafs.empty?
leafs.clear
find_reverse_leaf_paths(node, prefix, paths)
end
end
leafs.each do |leaf|
paths.push(prefix + [leaf])
end
prefix.pop unless leafs.empty?
paths.map { |path| path.reverse }.reverse
end
puts find_reverse_leaf_paths(tree).inspect
答案 2 :(得分:0)
只是想到我的头脑,为什么不能反复地遍历树,逐步连接节点,当你到达一个叶子输出节点时,它们的顺序相反。这应该为您提供所需的4个平面阵列。
你的前2个叶子阵列会像这样发展:
1 - node
12 - node
123 - leaf - output 321.
12 - pop out
124 - leaf - output 421
NWS
答案 3 :(得分:0)
为了澄清我在之前对这个问题的评论中试图提出的观点,我将展示一些代码。我只使用一个数组作为树,所以空树必须[root, []]
(因此保护空子)。
class Array
def paths
root, children = self
return [root] if children.empty?
children.map do |child|
(child.is_a?(Array) ? child.paths : [[child]]).map do |tail|
[root] + tail
end
end.flatten(1)
end
end
tree = [1, [[2, [3, 4]], [5, [[6, [7]], 8]]]]
p tree.paths
# [[1, 2, 3], [1, 2, 4], [1, 5, 6, 7], [1, 5, 8]]
当然,这不是你的输入,也不是你想要的结果;-)但它是同一个想法,不是吗?我的观点是,如果数据结构是“逻辑”,那么代码应该非常简单(并且功能齐全,走一棵树,我们不需要一个命令式算法!)。