【发布时间】:2018-02-17 13:09:41
【问题描述】:
在对应的多重集包含N 元素的multiset<int>::iterator 类型对象上应用next() 和prev() 函数的时间复杂度是多少?
我知道在 STL 中,多重集被实现为平衡的二叉搜索树,因此我希望每次操作的时间复杂度为 O(log N)(在最坏的情况下),以防我们只是遍历树直到我们找到合适的值,但我有预感这应该是平均 O(1)。
但是如果树是这样实现的——在平衡二叉搜索树中插入元素x时,我们还可以检索到树中小于x的最大数和大于@的最小数987654327@ 在 O(log N) 中。因此理论上,我们可以让树中的每个节点都维护指向其next 和prev 元素的指针,以便next() 和prev() 然后在每个查询中以恒定时间运行。
有人可以分享一下发生了什么吗?
【问题讨论】:
-
嗯,好问题;我认为 O(1)(甚至不是平均,只是 O(1)),但没有标准的钻研无法找到证据。平均而言,保持 O(1) 而不是 O(1) 可能需要工作。
-
是的!在我的 O(1) 方法中,它最终可能会使集合中的插入和删除操作慢两倍,因为在插入元素之前必须进行两次查找来记录指针。但这并不意味着没有更有效的方法:)
-
我认为该标准仅直接保证迭代器操作的恒定摊销时间复杂度 (iterator.requirements.general#10)。我没有找到特定容器的更精确信息(容器上的操作有特定的复杂性,但容器的迭代器上没有)。
-
@BanachTarski:您不需要进行额外的查找来维护线程树(其中每个节点都有下一个/上一个指针)。您始终可以在给定节点之前或之后将新节点插入到双向链表中,并且在 BST 搜索算法结束时,您始终知道其中一个相邻节点。然而,线程显着增加了节点的大小,使其成为空间/时间的权衡,我认为实现通常会选择空间。
-
@Yakk 虽然 可能 实现
O(1)最坏情况迭代器,但由于额外的缓存占用空间,没有人这样做。
标签: c++ algorithm c++11 binary-search-tree multiset