【问题标题】:iterator++ complexity for stl map [closed]stl map的迭代器++复杂性[关闭]
【发布时间】:2024-01-19 01:17:02
【问题描述】:

stl RB-Tree(set or map)的iterator++操作的复杂度是多少? 我一直认为他们会使用索引,因此答案应该是 O(1),但最近我阅读了 vc10 实现并震惊地发现他们没有。 要在有序 RB-Tree 中找到下一个元素,需要花费时间搜索右子树中的最小元素,或者如果节点是左子节点且没有右子节点,则搜索右兄弟节点中的最小元素。这引入了一个递归过程,我相信 ++ 运算符需要 O(lgn) 时间。 我对吗?这是所有 stl 实现的情况还是只是 Visual C++ 的情况?

维护 RB-Tree 的索引真的很难吗?据我所知,通过在节点结构中保存两个额外的指针,我们可以维护一个与 RB-Tree 一样长的双向链表。他们为什么不这样做?

【问题讨论】:

  • 请不要咆哮。编译器的实现者对他们的实现更加乐观,而且比我们以往任何时候都更加乐观。
  • 这种问题不适合堆栈溢出。堆栈溢出显然不利于讨论或意见,而是有利于主观事实。也许堆栈交换网络中的另一个站点更适合这个问题。

标签: c++ stl time-complexity


【解决方案1】:

在整个容器上递增迭代器时的摊销复杂度为每次递增 O(1),这是标准所要求的全部。你是对的,单个增量只有O(log n),因为树的深度具有那种复杂性。

在我看来,map 的其他 RB-tree 实现可能会类似。正如您所说,operator++ 的最坏情况复杂性可以得到改善,但成本并非微不足道。

链表很可能会提高迭代整个容器的总时间,但这并不确定,因为更大的节点结构往往会导致更多的缓存未命中。

【讨论】: