我有以下嵌套数据结构:
Node 1
|--- Node 11
|--- Node 111
|--- Node 12
|--- Node 121
|--- Node 122
|--- Node 123
|--- Node 13
|--- Node 131
Node 2
|--- Node 21
|--- Node 211
|--- Node 212
etc.
我正在尝试编写一种算法,将其转换为“普通”2D矩阵,如下所示:
| 1 | 11 | 111 |
| 1 | 12 | 121 |
| 1 | 12 | 122 |
| 1 | 12 | 123 |
| 1 | 13 | 131 |
| 2 | 21 | 211 |
| 2 | 21 | 212 |
etc.
然而,我有效地做它有点麻烦,因为我不能只遍历树并填充矩阵:因为你可以看到矩阵比树有节点有更多的单元,由于冗余数据在除最后一列之外的所有列中。
请注意,与示例中一样,树的所有叶子将具有相同数量的父节点,即:相同的“嵌套深度”,因此我不需要考虑较短的分支。
我确信已经有一个算法可以正常完成,但我不知道这个特殊问题是如何被调用的,所以我找不到它。任何人都可以帮助我吗?
答案 0 :(得分:2)
我不确定是否有任何特定的名称,也许"树扁平"但我想有几种方法可以让你平整一棵树。你可以用这样的东西(伪代码,因为没有语言标签)来做到这一点:
proc flatten_tree(tree : Node<Int>) : List<List<Int>>
matrix := []
flatten_tree_rec(tree, [], matrix)
return matrix
endproc
proc flatten_tree_rec(tree : Node<Int>, current : List<Int>, matrix : List<List<Int>>)
current.append(tree.value)
if tree.is_leaf()
matrix.append(current.copy())
else
for child in tree.children()
flatten_tree(child, current, matrix)
loop
endif
current.remove_last()
endproc
如果你需要生成一个需要预先分配的实际矩阵,你需要两次传递,一次计算叶子和深度的数量,另一次用来实际填充矩阵:
proc flatten_tree(tree : Node<Int>) : List<List<Int>>
leafs, depth := count_leafs_and_depth(tree, 0)
matrix := Matrix<Int>(leafs, depth)
flatten_tree_rec(tree, [], matrix, 0)
return matrix
endproc
proc count_leafs_and_depth(tree : Node<Int>, base_depth : Int) : Int
if tree.is_leaf()
return 1, base_depth + 1
else
leafs := 0
depth := 0
for child in tree.children()
c_leafs, c_depth := count_leafs_and_depth(child, base_depth + 1)
leafs += c_leafs
depth = max(c_depth, depth)
loop
return leafs, depth
endif
endproc
proc flatten_tree_rec(tree : Node<Int>, current : List<Int>, matrix : Matrix<Int>, index : Int)
current.append(tree.value)
if tree.is_leaf()
matrix[index] = current
index += 1
else
for child in tree.children()
index = flatten_tree(child, current, matrix, index)
loop
endif
current.remove_last()
return index
endproc