【发布时间】:2015-05-02 13:24:30
【问题描述】:
问题:STL红黑树(stl_tree.h)的有序迭代时间复杂度是O(N ln N)吗? 网上搜了一圈没找到答案。
我认为任何 ADT 的有序迭代的时间复杂度都应该是 O(N)。如果我错了,请告诉我。
我从这段代码中查看了 STL RB 树 (https://www.sgi.com/tech/stl/stl_tree.h)
迭代器的 ++ 运算符似乎不是 O(1) 而是 O(ln N)。
void _M_increment()
{
if (_M_node->_M_right != 0) {
_M_node = _M_node->_M_right;
while (_M_node->_M_left != 0)
_M_node = _M_node->_M_left;
}
else {
_Base_ptr __y = _M_node->_M_parent;
while (_M_node == __y->_M_right) {
_M_node = __y;
__y = __y->_M_parent;
}
if (_M_node->_M_right != __y)
_M_node = __y;
}
}
如果我没记错的话,上面的代码是 O(ln N) 复杂度而不是 O(1)。
那么下面的 ++ 运算符也会有 O(ln N) 的复杂度。
_Self& operator++() { _M_increment(); return *this; }
_Self operator++(int) {
_Self __tmp = *this;
_M_increment();
return __tmp;
}
这意味着即使是对 STL RBTree 的简单迭代也将是 O(N ln N) 而不是 O(N)。
我错了还是做了一些奇怪的假设?
顺便说一句,我想到了基于堆栈的迭代器堆叠路径。 我认为它可以实现 O(1) 时间复杂度,但它会花费 O(ln N) 空间复杂度,就像基于递归的中序遍历会花费一样。
但是,堆栈方法的问题是当不同的线程更改树结构并通过旋转弄乱路径堆栈时。 (但大多数时候,当我们考虑使用这种类型的 ADT 进行多线程编程时,我们通常会锁定整个树,所以路径混乱并不是什么大问题......对吗?)即使是这种类型的 O (ln N) 方法无论如何都不是线程安全的。
提前致谢。
【问题讨论】:
-
我认为这个问题与重复的候选人没什么不同。但是,如果您仍然认为这个问题是一个真正的重复。请删除此问题。
标签: c++ algorithm stl red-black-tree