【问题标题】:Iteratively traverse through tree to find size迭代遍历树以查找大小
【发布时间】:2011-11-21 17:06:57
【问题描述】:

我需要使用迭代算法查找树中元素的数量,但我发现代码在概念上很难编写。

我的做法是从根节点开始,访问子节点,然后是这些子节点的子节点,以此类推。

这是我编写的适用于小树的代码,但不是真正的解决方案,因为我需要为每个深度级别添加一个额外的块:

// Start the counter at 1 because the root node counts
int size = 1;

for(ITree child1 : root) {
    size++;
    for(ITree child2 : child1) {
        size++;
        for(ITree child3 : child2) {
            size++;
            for(ITree child4 : child3) {
                size++;
                for(ITree child5 : child4) {
                    size++;
                }
            }
        }
    }
}
return size;

【问题讨论】:

  • 我认为这是一个与您类似的问题:stackoverflow.com/questions/547622/…也许您可以在那里找到一些答案。
  • 我之前读过,它很有帮助,但是这棵树不是二元树,我需要迭代地做。

标签: java tree iteration


【解决方案1】:

从概念上讲,保留一个堆栈(LinkedList 等)。对于每个孩子(现在,您的孩子循环),添加到堆栈中。继续循环遍历堆栈,直到它最终为空。

这未经测试,但这应该完全符合您的要求。我只是使用java.io.File 而不是你的“ITree”,因为它是我可以编译的东西:

int sizeOfTree(File root){
    // Start the counter at 1 because the root node counts

    int size = 1;

    LinkedList<File> stack = new LinkedList<File>();
    stack.add(root);

    while(!stack.isEmpty()){
        File f = stack.remove();
        for(File child : f.listFiles()){
            size++;
            stack.add(child);
        }
    }

    return size;
}

【讨论】:

  • 使用 LinkedList 将提供请求的“迭代”遍历,而不是使用递归 - 这可能导致堆栈溢出。
  • 仍然不明白发生了什么,但从投票来看你是正确的,所以还是谢谢你:)
  • 感谢您的接受 - 但我想帮助您消除任何困惑。我能详细说明什么?
  • 我可以质疑你代码的每一行,所以我会质疑我认为的要点——堆栈存储是什么以及为什么?
  • 通过使用“堆栈”数据结构,我们实质上是在堆上存储有关堆栈的信息,而不是使用递归 - 它使用 JVM 的内部堆栈。不同之处在于,JVM 的堆栈不是只保留要处理的剩余项目(如我的示例),而是保留每次调用堆栈时使用的所有变量等。所以“递归”有时更容易设置,但迭代方法通常会更好地扩展。简而言之 - “堆栈”列表存储有关要处理的项目的信息,以防止使用递归函数调用。
【解决方案2】:

使用递归数据结构

实际上不可能迭代遍历递归数据结构,例如带有指针的树 - 这是因为对象“隐藏”了它们的底层数据元素。

使用不同的数据结构

所有树都可以存储/实现为线性数组数据结构,其中索引可以使用指数数学计算:

例如,一棵树 [0, 1, 2, 3, null, 4,null] 将描述一棵树,其根为 0,其中 0 有直接子节点 1 和 2。然后 1 有左子节点“3 ",并且 2 留下了孩子 "4"。

因此,如果以这种方式存储树,则元素的数量自然就是数组中非空元素的数量。

更简单地说:将树存储在线性结构中,您可以在任何给定时间知道长度,而无需制作任何花哨的算法。

【讨论】:

    【解决方案3】:

    你的任务的关键词是递归。树是一种经典的递归结构,因此您应该编写接受根节点的递归方法,计算该节点的大小,然后为所有子节点调用自身。这是伪代码:

    public int getSize(ITree root) {
        return getSize(root, 0);
    }
    
    private int getSize(ITree node, int size) {
        size++;
        for(ITree child : node.children()) {
            size += getSize(child, size)
        }
        return size;
    }
    

    【讨论】:

    • 但这不仅仅是递归的,它也是迭代的。我可以只使用递归吗?还是只有迭代? (不是两者)
    • 请解释一下您所说的“交互式”是什么意思
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-10
    • 2019-12-01
    • 2021-10-30
    • 2014-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多