【问题标题】:How to calculate leaf nodes in a nested data structure in Java?如何在 Java 中计算嵌套数据结构中的叶节点?
【发布时间】:2011-02-04 23:27:19
【问题描述】:

我有一个类似这样的结构,我们称之为 Box 对象。

Box--+---Box----Box
     |
     +---Box-+--Box
             |
             +--Box
             |
             +--Box

我正在尝试向顶部框对象询问叶节点框的列表,在本例中是 3 个框对象。

box 对象在一个称为 children 的 Vector 类型的实例变量中包含一个子对象列表。

孩子的数量可以不受限制。

我一直在尝试编写一个递归方法来执行此操作,但没有成功。

【问题讨论】:

  • 到目前为止你有什么?
  • 三个盒子对象?不是有四片叶子吗?

标签: java algorithm data-structures nodes


【解决方案1】:

一种方法是递归遍历结构。思路如下:

  1. 空树中没有叶子节点。
  2. 在根为 r 且没有子节点的树中,r 是唯一的叶子。
  3. 在根为 r 的树中,如果 r 有孩子,那么树的叶子就是这些孩子的叶子。

您可以使用这种伪代码编写递归遍历:

void findChildren (Box current, List<Box> found) {
    /* Case 1. */
    if (current == null) return;

    /* Case 2. */
    if (current.children.isEmpty()) {
        found.add(current);
        return;
    }

    /* Case 3. */
    for (Box child: current.children)
        findChildren(child, found);
}

希望这会有所帮助!

【讨论】:

  • "在根为 r 的树中,如果 r 有孩子,那么树的叶子就是这些孩子的叶子。"在这种情况下,是的。但我敢肯定,在某些情况下,根的孩子会有孩子。我没有-1顺便说一句。那个人应该在那里留下自己的评论..
  • @Nicklammort:这是递归规则,它是真的。因为你进入了孩子们,他们再次应用了规则。
  • Falmarri,我明白这一点,但这并不意味着唯一的孩子是根的孩子。
  • 致那些投反对票的人——我希望能解释一下为什么这是不正确的。如果我犯了错误,我真的很想知道它是什么;这对我来说似乎是正确的。此外,如果问题是我解释得不好,我很想知道如何改进答案以使其更有用。我在这里是因为我真的很喜欢帮忙,如果有什么我可以做的改进,我很乐意听听你的意见。
【解决方案2】:

自从我做 Java 以来已经有一段时间了,所以我确信这段代码有很多语法错误,我希望没有人因此而为我打分;只是想给你一些算法的想法。希望对您有所帮助:

vector<Box> getLeaves(Box root)
{
    vector<Box> tempList;    //vector to hold nodes to check
    vector<Box> tempList2;   //vector to hold nodes' children
    vector<Box> leafList;
    bool goflag = true;

    tempList.add(root);

    while(goflag){
        for(int i = 0; i < tempList.size; i++){
            if(tempList[i].children.isEmpty()){
                leafList.add(tempList[i]);
            }
            else{
                //add all children to tempList2
                for(int c = 0; c < tempList[i].children.size; c++){
                    tempList2.add(tempList[i].children[c])
            }
        }
        if(tempList2.isEmpty()) //no more childs
            goflag = false;
        else
            tempList = tempList2;
        tempList2.clear();
    }
    return leafList;
}

它遍历所有节点,将子节点添加到下一个要检查的列表中,并将叶子添加到要返回的列表中。

【讨论】:

    【解决方案3】:

    有几种方法可以编写这样的函数。这是一种解决方法。

    • 定义一个辅助函数,该函数接受一个节点和一个持有节点的可变队列。
    • 在该辅助函数中,检查提供的节点的子节点是否为空。如果是,则将该节点添加到队列中,然后返回。
    • 如果提供的节点有任何子节点,则为每个子节点调用一次帮助函数,传递子节点和相同的队列引用。
    • 在顶层,创建一个空队列,并调用辅助函数,传入根节点和队列。
    • 当辅助函数返回时,队列会按照发现的顺序包含所有叶子。

    另一种方法使用相同的深度优先遍历,但该函数将返回它发现的叶子列表。需要为探索的每组同级组合这些列表,并在每个函数调用返回时备份树。

    【讨论】:

    • 是的,这已经足够接近了。当我开始输入这个答案时,我没有注意到另一个答案。
    猜你喜欢
    • 2022-11-16
    • 2019-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多