【问题标题】:run time complexity of std::list::push_back()std::list::push_back() 的运行时间复杂度
【发布时间】:2015-01-03 12:08:21
【问题描述】:

以下代码的运行时间复杂度是多少

std::list<int> a;
a.push_back(1); //initialize
a.push_back(2);
a.push_back(3);
std::list<int>::iterator i = a.begin();
std::cout<<*(++i); // displays 2
std::cout<<*(++i); // displays 3

我正在编写一个目前在数据挖掘领域的程序,我需要注意它的时间副性能。我只是有一个疑问(我以前没有,因为我不关心我早期程序中的时间复杂度,因为它们是直截了当的)。因此,在更安全的方面,我想询问将元素添加到列表 a 的实际时间复杂度。上面表现得像数组的指针'i'让我怀疑它是否真的是一个数组或一个重载了++和*运算符的对象。

如果 'i' 是一个数组,那么 std::list::push_back() 的时间复杂度应该是 O(n),这对于我的情况来说是不希望的。但如果不是,您能否解释运算符 * 和 ++ 所继承的算法,以便确定它们的时间复杂度?是否建议为我的案例使用列表? (如果 'i' 不是一个数组,那么假设 std::list::push_back() 的时间复杂度为 O(1) 是安全的)

对不起,我以前版本的问题不太可读

【问题讨论】:

  • 我认为没有指针数组,列表中的元素指向下一个(和上一个)元素。
  • 为什么你认为是O(N^2)???
  • *(++i) 怎么样?不像访问数组吗?
  • @chessHacker 这是一个迭代器,他们的 *++ 运算符重载。它们的行为不像在数组中。 * 确实取消引用迭代器。但 it++ 会跳转到列表中的下一个元素,而不是数组中。根据定义,列表元素在内存中并不相邻。
  • @chessHacker 就像访问迭代器一样。在某些方面,迭代器的接口与指针非常相似。

标签: c++ arrays list c++11 time-complexity


【解决方案1】:

所以应该有一个指针数组,每个指针指向链表中的每个节点。每次我们调用 push_back() 成员函数时,指针数组都应该被清除并重新分配;你不这么认为吗?

不,我不这么认为。标准中没有提到这样的数组,在 list 容器中有这样的数组会很奇怪。

作为旁注: 如果存在这样的数组,那么它的增长将是 O(n),而不是 O(n^2)。如果插入的大小在已满时相乘,这可能会使插入摊销 O(1),例如 std::vector 会如何做。

【讨论】:

  • 是的,但是当我们在上述情况下增加 i 时会发生什么? i 是一个指针,所以 i++ 应该代表下一个数组元素对吗?就像在 i[1] 中,它与 *(i+1) 相同
  • i 不是指针,而是迭代器。 i++ 表示列表中下一个元素的迭代器,与任何数组无关。迭代器的接口与指针非常相似(指针可以用作数组的迭代器,但标准容器有其他类型的迭代器)。
【解决方案2】:

std::list 通常是双向链表实现,而不是数组实现。另一方面,std::list 是双向链表的更高层次抽象。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-15
    • 1970-01-01
    • 2019-03-13
    • 2020-10-13
    相关资源
    最近更新 更多