相关问题:Time Complexity of InOrder Tree Traversal of Binary Tree O(N)?,但是它基于遍历递归(所以在O(log N)空间中),而迭代器只允许消耗O(1)空间。
在C ++中,通常需要将标准容器的迭代器递增为O(1)操作。对于大多数容器来说,它已被轻易证明,但是map
等等,似乎有点困难。
map
被实现为跳过列表,那么结果将是显而易见的因此,在有序遍历期间,有时候“下一个”值不容易达到。例如,如果您指向左子树的右下方叶子,则要遍历的下一个节点是根,距离depth
步。{/ p>
我已经尝试“证明”算法复杂度(根据“步骤”)摊销 O(1),这似乎没问题。但是我还没有进行演示。
这是我为深度为4的树追踪的一个小图,数字(在节点的位置)表示在有序遍历期间从该节点到下一个节点的步数:
3
2 2
1 1 1 1
1 2 1 3 1 2 1 4
注意:最右边的叶子的成本为4,以防这是一棵较大树的子树。
总和为28,总节点数为15:因此平均每个节点的成本小于2,(如果它保持不变)将是一个很好的摊销成本。所以:
答案 0 :(得分:9)
是的,对于任何树,每次迭代的摊还成本确实为O(1)
。
证明基于您“访问”每个节点的次数。
叶子只参观一次。
没有叶子最多访问3次:
不再访问任何节点,因此如果我们总结每个节点的访问次数,我们会得到一个小于3n
的数字,因此所有节点的总访问次数为{ {1}},每步我们O(n)
摊销。
(注意,因为在完整的树中有n / 2个叶子,我们得到了您遇到的O(1)
,我相信可以证明访问量的总和小于2n
任何树,但这种“优化”超出了IMO的范围。
每个步骤的最差情况为2n
,在平衡树中为O(h)
,但在某些情况下可能为O(logn)
。
P.S。我不知道如何在C ++中实现Red-Black树,但如果您的树数据结构包含来自每个节点的O(n)
字段,它可以替换递归堆栈并允许parent
空间消耗。 (这当然是“作弊”,因为存储O(1)
这样的字段本身就是n
。