当前位置: 首页 > 面试题库 >

将一系列父子关系转换为层次树?

南宫鸿晖
2023-03-14
问题内容

我有一堆名称-父母名对,我想将其变成尽可能少的分层树结构。因此,例如,这些可能是配对:

Child : Parent
    H : G
    F : G
    G : D
    E : D
    A : E
    B : C
    C : E
    D : NULL

需要将其转换为一个或多个分层树:

D
├── E
│   ├── A
│   │   └── B
│   └── C   
└── G
    ├── F
    └── H

我想要的最终结果是一组嵌套<ul>元素,每个元素都<li>包含孩子的名字。

配对中没有不一致的地方(子代是它自己的父代,父代是子代的子代,等等),因此可以进行大量优化。

在PHP中,如何从包含child => parent对的数组转到一组Nested <ul>

我感觉涉及到递归,但是我还没有足够清醒地思考它。


问题答案:

这需要一个非常基本的递归函数来将子/父对解析为树结构,并需要另一个递归函数来将其打印出来。只有一个函数就足够了,但是为了清楚起见,这里有两个(可以在此答案的末尾找到一个组合函数)。

首先初始化子对/父对对的数组:

$tree = array(
    'H' => 'G',
    'F' => 'G',
    'G' => 'D',
    'E' => 'D',
    'A' => 'E',
    'B' => 'C',
    'C' => 'E',
    'D' => null
);

然后将数组解析为分层树结构的函数:

function parseTree($tree, $root = null) {
    $return = array();
    # Traverse the tree and search for direct children of the root
    foreach($tree as $child => $parent) {
        # A direct child is found
        if($parent == $root) {
            # Remove item from tree (we don't need to traverse this again)
            unset($tree[$child]);
            # Append the child into result array and parse its children
            $return[] = array(
                'name' => $child,
                'children' => parseTree($tree, $child)
            );
        }
    }
    return empty($return) ? null : $return;    
}

和遍历该树以打印出无序列表的函数:

function printTree($tree) {
    if(!is_null($tree) && count($tree) > 0) {
        echo '<ul>';
        foreach($tree as $node) {
            echo '<li>'.$node['name'];
            printTree($node['children']);
            echo '</li>';
        }
        echo '</ul>';
    }
}

以及实际用法:

$result = parseTree($tree);
printTree($result);

这是内容$result

Array(
    [0] => Array(
        [name] => D
        [children] => Array(
            [0] => Array(
                [name] => G
                [children] => Array(
                    [0] => Array(
                        [name] => H
                        [children] => NULL
                    )
                    [1] => Array(
                        [name] => F
                        [children] => NULL
                    )
                )
            )
            [1] => Array(
                [name] => E
                [children] => Array(
                    [0] => Array(
                        [name] => A
                        [children] => NULL
                    )
                    [1] => Array(
                        [name] => C
                        [children] => Array(
                            [0] => Array(
                                [name] => B
                                [children] => NULL
                            )
                        )
                    )
                )
            )
        )
    )
)

如果需要更高的效率,可以将这些功能合并为一个,并减少迭代次数:

function parseAndPrintTree($root, $tree) {
    $return = array();
    if(!is_null($tree) && count($tree) > 0) {
        echo '<ul>';
        foreach($tree as $child => $parent) {
            if($parent == $root) {                    
                unset($tree[$child]);
                echo '<li>'.$child;
                parseAndPrintTree($child, $tree);
                echo '</li>';
            }
        }
        echo '</ul>';
    }
}

您只会在这样小的数据集上保存8次迭代,但在较大的数据集上可能会有所作为。



 类似资料:
  • 问题内容: 我有一堆父母/孩子对,我想尽可能地变成分层树结构。因此,例如,这些可能是配对: 需要将其转换为(多个)分层树: 在Java中,我如何从包含child => parent对的arrayList转到这样的Tree? 我需要此操作的输出是arrayList包含两个元素D和X,每个元素依次具有其子级列表,而子级又包含子级列表,依此类推 我的第一次尝试是 再试一次 问题答案: 这是基于第一个答案

  • 我有一个场景,需要在一种情况下加载所有子值,在另一种情况下加载一些特定的子值。我对这两种情况都使用一个bean,并使用命名查询编写查询。 现在在我的查询2中,我只需要加载字符串A,而不需要加载字符串B和字符串C。我试过使用 但得到以下错误 那么,关于如何继续这方面的任何建议。。

  • 使用JPA(Hibernate)我试图实现以下关系,并想知道其他人是否对最佳方法有任何建议: 基本上是完全不相关的对象,每个对象都有一个公共子对象的集合;在对象模型中实现简单,在数据库中稍微麻烦些! 我确信这一定是常见的事情,但是我很难找到任何示例实现,因为我真的不知道正确的搜索词。 谢谢你的时间!

  • 问题内容: 我们有一个表,该表表示与实体(称为项目)关联的值树,其中ParentID列引用行的父级的id列。id列是一个自动递增的IDENTITY列和主键。根节点的ParentID为0。 我们希望能够克隆给定项目的数据,并使生成的ParentID引用复制值的相应新ID,其方式应满足示例中所述的限制。 例如,在下表中复制ProjectID 611的数据: 应导致: 限制: 解决方案必须适用于 SQL

  • 问题内容: 我有一个数据框(df),看起来像: 对于整个时间序列,我尝试将今天的值除以昨天,并使用以下命令记录结果: 但是我得到以下错误: 我怎样才能解决这个问题?我试图使用以下方法将其转换为float: 但是什么也无法工作。 问题答案: 您可以改用numpy.log。Math.log需要一个数字,而不是数组。

  • 问题内容: 如何将以下SQL查询转换为ActiveRecord关系,以便可以使用范围对其进行扩展? 这是我必须尝试直接使用Arel的东西吗? 我尝试将其分解为作用域/子查询,但是子查询上的选择最终在封闭查询中,因此引发PostgreSql错误,因为未在封闭语句中的GROUP BY或ORDER BY中指定该列。 更新: 您认为它是PostgreSql是正确的。我尝试了您的查询,但是对于直接查询和Ac