【问题标题】:How to get recursively get all leaves of a Tree Structure in Java如何在Java中递归获取树结构的所有叶子
【发布时间】:2016-02-20 10:02:19
【问题描述】:

我有一个树节点的数据库表,如下所示。我想用这些树节点用 Java 制作一个 ArrayList。 Arraylist 将在 Java 中以递归格式递归地获取所有树节点。

输入:

数据库表

Name            ID      Parent_ID
Parent          1   
Child-1         2           1
Child-1.1       3           2
Child-1.1.1     4           3
Child-2         5           1
Child-3         6           1
Child-1.1.1.1   7           4
Child-1.2       8           2

我想以下面的 Java 格式制作上表的 ArrayList,其中 Sub 是子节点的列表,如果没有子节点,则 Sub 为 Null。

public class Node {

    private String id;
    private String name;
    private String type;
    private String value;
    private List<Node> sub;
}

输出:

  1. 父母
    • 孩子-1
      • 儿童-1.1
        • 儿童-1.1.1
          • Child-1.1.1.1
      • Child-1.2
    • 孩子 2
    • 孩子 3

有人可以帮忙在 Java 中创建一个递归函数来实现上述内容吗?

【问题讨论】:

  • 到目前为止你有什么?你能想出一种迭代的方法吗(有助于提出一个递归版本)?
  • 你做了什么来尝试解决这个问题? StackOverflow 不是您的“做我的功课”网站
  • 为什么需要递归实现?
  • 嗨 Codor,我正在两个地图中获取数据库值: Map1 和 Map2 。从这两张地图中,我试图创建一个 ArrayList 递归地将元素推入其中。如下所示: List mainList = new ArrayList; for(Map1) { for(Map2) { if(map1.id.equals.map2.parentID) { mainList.add(map2.id); // 这将首先在列表中添加 4 个主要节点 (Child-1, Child-2, Child-3) } } } 现在我不知道如何将 Child-1.1 添加到 Child-1 的子字段中递归方式直到 n 次迭代。请指导。

标签: java recursion tree


【解决方案1】:

递归函数:

public void printTree(Node tree,int num)
{
    if(tree==null || tree.getSub()==null)return;
    for(Node n : tree.getSub())
    {
    System.out.println(new String(new char[num]).replace("\0", "   ")+"*"+n.getName());
printTree(n,num+1);
}
}

public void callRec(Node tree)
{
    System.out.println(tree.getName());
    printTree(tree,1);
}

结果将是:

Parent
*Child-1
  *Child-1.1
     *Child-1.1.1
        *Child-1.1.1.1
  *Child-1.2
*Child-2
*Child-3

【讨论】:

  • 嗨 Ben,我的列表将形成一个 Arraylist 具有包含子节点的子字段。我从数据库中获取它并根据我上面的问题形成 Arraylist
  • 嗨,Ben,最初,所有节点的子元素都将为空。我们需要根据条件填写子元素并制作子节点
【解决方案2】:

这个问题可以通过以下两步来解决,其中符号是一些Java-ish伪代码。首先,所有数据库行都必须放在List&lt;Node&gt; Nodes 中,其中Node 应该有一个额外的成员ParentID,并且必须构建实际的树结构。这可以按如下方式及时完成O(n^2),这不是最优的,但对节点索引没有额外的假设。

for (int i = 0; i < Nodes.Count(); i++) // iterate nodes
{
    for (int j = 0; j < Nodec.Count(); j++) // search parent of i-th node
    {
        if (Nodes[j].id.Equals(Nodes[i].ParentID)) // j-th node is parent of i-th node
        {
            Nodes[j].sub.add(Nodes[i]); // add i-th node to children of j-th node
        }
    }
}

之后,叶子可以很容易地识别出来,因为它们是没有子节点的节点。

for (int i = 0; i < Nodes.Count(); i++)
{
    if (Nodes[i].sub.Count() == 0) // i-th node is a leaf
    {
        // do something with a leaf
    }
}

请注意,我从头到尾对Java不太熟悉,但算法思想应该可以理解。

【讨论】:

  • 嗨 Codor,我正在两个地图中获取数据库值:
  • 嗨 Codor,我正在两个地图中获取数据库值: Map1 和 Map2 。从这两张地图中,我试图创建一个 ArrayList 递归地将元素推入其中。如下所示: List mainList = new ArrayList; for(Map1) { for(Map2) { if(map1.id.equals.map2.parentID) { mainList.add(map2.id); // 这将首先在列表中添加 4 个主要节点 (Child-1, Child-2, Child-3) } } } 现在我不知道如何将 Child-1.1 添加到 Child-1 的子字段中递归方式直到 n 次迭代。请指导。
  • 嗨 Codor,你的实现听起来不错..我会试试这个。但是您能否确认一下是否将 Child-1.1 添加到 Child-1 的子字段中。 if 将从主节点列表中删除。将元素添加到列表的子字段后,我是否应该从列表中显式删除它
  • 不需要删除节点;节点不会被删除。
  • 更准确地说,处理节点只是为了代表sub成员中的子关系。
【解决方案3】:

这是一个粗略的算法:

ArrayList<Integer> ar = new ArrayList<Integer>();

public extract(node root){
    foreach(node i : root.sub)
        extract(i);
    ar.add(i.value);
}

【讨论】:

  • 嗨,Noel,最初,所有节点的子元素都将为空。我们需要根据条件填写子元素并制作子节点
猜你喜欢
  • 2022-01-25
  • 1970-01-01
  • 1970-01-01
  • 2022-01-27
  • 2011-02-04
  • 2021-02-13
  • 1970-01-01
  • 2019-10-13
  • 2023-03-24
相关资源
最近更新 更多