[英]In-order traversal complexity in a binary search tree (using iterators)?
Related question: Time Complexity of InOrder Tree Traversal of Binary Tree O(N)? 相关问题: 二叉树O(N)的InOrder树遍历的时间复杂度? , however it is based on a traversal via recursion (so in O(log N) space) while iterators allow a consumption of only O(1) space.
但是它基于遍历递归(因此在O(log N)空间中),而迭代器只允许消耗O(1)空间。
In C++, there normally is a requirement that incrementing an iterator of a standard container be a O(1) operation. 在C ++中,通常需要将标准容器的迭代器递增为O(1)操作。 With most containers it's trivially proved, however with
map
and such, it seems a little more difficult. 对于大多数容器来说,它已被轻易证明,但是使用
map
等,似乎有点困难。
map
were implemented as a skip-list, then the result would be obvious map
实现为跳过列表,那么结果将是显而易见的 So, during an in-order traversal there are moments where the "next" value is not so easily reached. 因此,在有序遍历期间,有时候“下一个”值不容易达到。 For example should you be pointing at the bottom-right leaf of the left subtree, then the next node to traverse is the root, which is
depth
steps away. 例如,如果您指向左子树的右下方叶子,则要遍历的下一个节点是根,这是
depth
步长。
I have tried "proving" that the algorithmic complexity (in terms of "steps") was amortized O(1), which seems alright. 我试过“证明”算法的复杂性(就“步骤”而言)是摊销的 O(1),这似乎没问题。 However I don't have the demonstration down yet.
但是我还没有进行演示。
Here is a small diagram I traced for a tree with a depth of 4, the numbers (in the place of the nodes) represent the number of steps to go from that node to the next one during an in-order traversal: 这是我为深度为4的树追踪的一个小图,数字(在节点的位置)表示在有序遍历期间从该节点到下一个节点的步数:
3
2 2
1 1 1 1
1 2 1 3 1 2 1 4
Note: the right-most leaf has a cost of 4 in case this would be a sub-tree of a larger tree. 注意:如果这是一棵较大树的子树,则最右边的叶子的成本为4。
The sum is 28, for a total number of nodes of 15: thus a cost less than 2 per node, in average, which (if it holds up) would be a nice amortized cost. 总和为28,总节点数为15:因此平均每个节点的成本小于2,(如果它保持不变)将是一个很好的摊销成本。 So:
所以:
Yes, the amortized cost is indeed O(1)
per iteration, for a any tree. 是的,对于任何树,摊销成本实际上是每次迭代的
O(1)
。
The proof is based on the number of times you "visit" each node. 证明基于您“访问”每个节点的次数。
Leaves are visited only once. 叶子只访问过一次。 None leaves are visited at most 3 times:
没有叶子最多访问3次:
There are no more visits to any nodes, thus if we sum the number of visits of each node, we get a number that is smaller then 3n
, so the total number of visits of all nodes combined is O(n)
, which gives us O(1)
per step amortized. 没有更多的访问任何节点,因此如果我们总结每个节点的访问次数,我们得到一个小于
3n
,所以所有节点的总访问次数是O(n)
,这给了我们每步O(1)
摊销。
(Note since in a full tree there are n/2 leaves, we are getting the 2n
you were encountering, I believe one can show that the sum of visits will be smaller then 2n
for any tree, but this "optimization" is out of scope here IMO). (注意,因为在一个完整的树中有n / 2个叶子,我们得到你遇到的
2n
,我相信可以证明任何树的访问总和将小于2n
,但是这个“优化”不在范围在这里IMO)。
The worst case per step is O(h)
, which is O(logn)
in a balanced tree, but might be O(n)
in some cases. 每步的最坏情况是
O(h)
,它是平衡树中的O(logn)
,但在某些情况下可能是O(n)
。
PS I have no idea how Red-Black trees are implemented in C++, but if your tree data structure contains a parent
field from each node, it can replace the recursive stack and allow O(1)
space consumption. PS我不知道如何在C ++中实现Red-Black树,但如果您的树数据结构包含来自每个节点的
parent
字段,它可以替换递归堆栈并允许O(1)
空间消耗。 (This is of course "cheating" because storing n
such fields is O(n)
itself). (这当然是“作弊”,因为存储
n
这样的字段是O(n)
本身)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.