【问题标题】:Iterating over binary tree w/o control of stack or dynamic allocation在不控制堆栈或动态分配的情况下迭代二叉树
【发布时间】:2009-11-15 23:10:16
【问题描述】:

在给定以下约束的情况下,是否有一种高效、实用的方法来遍历二叉树:

  1. 您无法控制调用堆栈,因此不能使用递归。所有状态都必须存在于迭代器/范围对象内,而不是堆栈上。
  2. 不得在算法中的任何地方使用堆分配。
  3. 树可能是不可变的,因此您无法在其中存储迭代状态。
  4. 您没有父指针。
  5. 迭代器/范围结构不能太大,以至于传递给函数是完全不合理的。

编辑:

  1. 这不是家庭作业。实际上,我正在尝试设计一个库,该库在第二个堆栈上构建二叉树,并对堆分配(或缺乏堆分配)做出很多保证。
  2. 树木是平衡的。 (它们是 AVL 树。)

【问题讨论】:

  • 这是一个挑战,还是只是家庭作业?

标签: algorithm data-structures iterator range binary-tree


【解决方案1】:

它只能对深度达到一定限制(因此元素数量)的树进行,因为它需要与树深度成比例的辅助内存;在您迭代一个项目时,您需要跟踪下一个要进行的项目,如果您处于最深的叶子之一,那么所需的“保持跟踪指针”的数量将是仅比树的深度小 1。例如,如果您可以接受将深度限制为 32(因此不超过 4,294,967,295 个节点),则需要一个由 32 个指针(加上一个索引)组成的辅助固定大小数组。

对于不完全退化的二叉树(因此具有大致与2**depth 成比例的节点数量,而不仅仅是与depth;-),这个固定数量的辅助内存应该是可以接受的——即,只需按log(N) 指针的顺序修复辅助内存,以在最多具有N 节点的任何树上进行迭代。如果这是不可接受的,那么您的问题的答案是“那里……?”是没有;-)。

【讨论】:

    【解决方案2】:

    如果保证您的树按其值排序并且这些值严格按升序排列(所有 B > A,而不仅仅是 B >= A),那么您可以不使用动态内存遍历无限大小的树。不过,你的性能确实受到了影响。

    要找到值 A 之后的下一个值,只需再次下降到树中,执行二进制(当然)搜索一个刚好大于 A 的值。

    我只是想到了这个。如果有人能证明我的想法是错误的,那就去吧!

    【讨论】:

    • 好主意,这意味着您可以在 O(N log N) 中迭代树。如果您将其与固定大小的堆栈相结合,这样您只需要非常不频繁地进行此搜索,那么对于任何实际的树大小,该算法的性能将更类似于 O(N) 算法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-07
    • 2011-05-08
    • 2014-05-08
    • 2016-08-30
    • 2020-10-06
    相关资源
    最近更新 更多