算法 - 将嵌套数据转换为普通数据

标签 algorithm matrix tree

我有以下嵌套数据结构:

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.  

我正在尝试编写一种算法,将其转换为“普通”二维矩阵,如下所示:

| 1  | 11  | 111 |  
| 1  | 12  | 121 |  
| 1  | 12  | 122 |  
| 1  | 12  | 123 |  
| 1  | 13  | 131 |  
| 2  | 21  | 211 |  
| 2  | 21  | 212 |  
etc.

但是,我在高效地执行此操作时遇到了一些麻烦,因为我不能只遍历树并填充矩阵:如您所见,由于冗余数据,矩阵的单元数多于树的节点数在除最后一列之外的所有列中。

请注意,就像在示例中一样,树的所有叶子都将具有相同数量的父节点,即:相同的“嵌套深度”,因此我不需要考虑较短的分支。

我确信已经有一个算法可以正确地做到这一点,但我不知道这个特定问题是如何被调用的,所以我找不到它。谁能帮帮我?

最佳答案

我不确定这有什么具体的名称,也许是“树扁平化”,但我想有几种方法可以使树扁平化。你可以用这样的东西来做(伪代码,因为没有语言标签):

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

关于算法 - 将嵌套数据转换为普通数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49985409/

相关文章:

algorithm - 上下文无关文法

c++ - 涉及指针和手动实现的矩阵类的问题

python - 如何对存储为嵌套列表的巨大矩阵 (100000x100000) 进行操作?

c# - 在树结构中使用数据模型实现存储库模式

java - 使用 Java 逐层构建树

algorithm - 网络流算法的适当图形表示

c# - 在一定权重下找到所有后续替换的最佳算法

c++ - 广度优先搜索中的问题

r - 如何合并数据集而不在一个有多个值的地方循环?

c++从二叉搜索树中删除具有两个子节点的特定节点