【问题标题】:Tree traversal with fixed size stack in C/C++在 C/C++ 中具有固定大小堆栈的树遍历
【发布时间】:2012-02-05 11:04:08
【问题描述】:

是否可以使用固定大小的堆栈来遍历树结构(特别是八叉树,二叉树的 3-D 版本)?我不想使用递归,因为我的八叉树是 很深。

我正在遍历树进行范围搜索问题,以找到最接近查询点的所有点。所以在我的遍历中,我不会沿着那些以我的搜索区域不相交的节点为根的子树向下走。

【问题讨论】:

标签: c++ c algorithm


【解决方案1】:

如果你的八叉树有父指针,我认为你可以在没有堆栈的情况下遍历它(例如,参见this thread)。否则,无论跳过多少分支,您都需要一个与树的深度一样深的堆栈。

【讨论】:

    【解决方案2】:

    当然,您可以在不使用深层本机调用堆栈的情况下,使用延续传递风格技术,或者(这大致相同)通过制作虚拟机,将其调用堆栈实现为堆数据,或者(另一种观点)通过编码堆栈自动机,堆栈实现为显式堆数据结构(例如std::stack)。

    想一想,你的 C++ 幼稚代码可以在图灵机上运行,​​而这些野兽没有任何堆栈。

    正如Ted Hopp's answer 建议的那样,您可能会受到Deutsch-Schorr-Waite 的垃圾收集技术的启发(每个节点有一些额外的位来临时翻转参考方向并记住这一点)进行“无堆栈”遍历(但您需要在每个节点中添加额外的位)。但我相信在std::stackstd::vector 中拥有自己的堆栈可能更简单。

    【讨论】:

    • “任何其他名字的玫瑰...” 继续传递样式使用堆栈。用堆来实现栈还是栈。在图灵机上模拟堆栈仍然是使用堆栈。此外,OP 似乎在询问任何堆栈,而不是专门询问调用堆栈。问题似乎是额外的内存使用,而不是避免明确称为“堆栈”的结构。
    • 我同意,我从没想过。我刚刚谈到了避免深度本机调用堆栈;而我对“避免深度递归”的理解仅与机器堆栈有关。
    【解决方案3】:

    可以,可以用固定大小的栈遍历八叉树。

    固定大小只需要与可能的最长八叉树深度一样大。

    请记住,使用八叉树,每次深度遍历只需 3 位内存即可记录。对于三个维度中的每一个维度,你只需要记录你是走的是正向还是负向。

    因此,即使您的八叉树深度为 1000,您也可以存储 375 个字节的递归。

    【讨论】:

    • 这不是一个固定大小的堆栈。对于任何固定的 N,都会有如此深的八叉树,以至于递归不能存储在 N 个字节中。 (10^-1000)*log(N) 仍然是 O(log N)。
    • @TedHopp:你的数学是正确的,但是“会有这么深的八叉树”是一个理论假设,不是吗?这似乎是一个现实世界的问题。
    猜你喜欢
    • 2011-03-13
    • 1970-01-01
    • 2014-06-05
    • 1970-01-01
    • 1970-01-01
    • 2012-08-09
    • 2016-02-09
    • 2011-12-05
    • 2012-09-12
    相关资源
    最近更新 更多