【发布时间】:2011-06-02 16:00:45
【问题描述】:
我最近一直在编写一堆不同的二叉搜索树实现(AVL、splay、treap),我很好奇是否有一种特别“好”的方法来编写迭代器来遍历这些结构。我现在使用的解决方案是让 BST 中的每个节点都存储指向树中下一个和前一个元素的指针,这将迭代减少为标准的链表迭代。但是,我对这个答案并不满意。它通过两个指针(下一个和上一个)增加每个节点的空间使用量,在某种意义上它只是作弊。
我知道一种构建二叉搜索树迭代器的方法,该迭代器使用 O(h) 辅助存储空间(其中 h 是树的高度),通过使用堆栈来跟踪边界节点以便稍后探索,但由于内存使用情况,我拒绝对此进行编码。我希望有一些方法可以构建一个只使用常量空间的迭代器。
我的问题是 - 有没有办法在具有以下属性的二叉搜索树上设计迭代器?
- 元素按升序访问(即中序遍历)
-
next()和hasNext()查询在 O(1) 时间内运行。 - 内存使用量为 O(1)
为了方便起见,如果您假设树结构在迭代期间没有改变形状(即没有插入、删除或旋转),那很好,但如果有一个解决方案确实可以处理这个。
【问题讨论】:
-
如果遍历的树是可变的,您可以使用 TAOCP I.2.3.1 遍历二叉树中的技巧,练习 21。它需要 O(N) 和 O(1) 内存。当算法完成时,树当然不会改变。它会和以前一样。
-
这似乎正是我正在寻找的答案。 :-)
-
你为什么担心在迭代器中存储一堆树节点的内存开销?如果平衡良好,则树中元素的数量只有 O(log n)。
-
我正在尝试最大化副本的渐近速度。使用堆栈使迭代器复制 O(lg n);我希望得到 O(1),因为 C++ 迭代器会被大量复制和传递。
-
Henson 代码对我来说似乎有点错误(不过我不完全确定)。在 BSTIterator
& operator++() 方法中,左下降应该是迭代的,即必须遍历到 m_curNode->GetRight() 的最左节点。
标签: algorithm iterator binary-search-tree