为什么对std::forward_list拼接整个列表或范围是线性的?
Why is splicing an entire list or a range linear for std::forward_list?
将一个范围从一个列表拼接到另一个列表可以在恒定时间内完成,但代价是size()
的复杂度为线性。
c++ 11改变了std::list
的情况,要求size()
为常数时间。例如,这打破了gcc的实现,参见[c++ 0x] std::list::size的复杂度。
除了范围splice()
, ,是否还有其他原因导致 size()
不能在早期的,符合c++ 03的 std::list
实现中成为常数时间?
为什么拼接整个列表或范围线性 std::forward_list
?
参见splice_after()
, case(1)和(3)。参见23.3.4.6 forward_list operations [forwardlist. cn]。ops]在标准草案N3485中。std::forward_list
甚至没有实现size()
。
我知道forward_list是一个单链表,但我不明白为什么不能在常数时间内做范围splice_after()
。我可能在这里遗漏了一些琐碎的东西…
EDIT:好吧,这至少部分是我的误解,我期望4将而不是留在源代码列表中。代码:
#include <algorithm>
#include <iostream>
#include <forward_list>
using namespace std;
void dump_list(const forward_list<char>& l) {
for(char c : l)
cout << c << ' ';
cout << 'n';
}
int main()
{
forward_list<char> trg = {'a','b','c'};
forward_list<char> src = {'1','2','3','4'};
auto first = src.begin();
auto last = find(src.begin(), src.end(), '4');
cout << "first = " << *first << ", last = " << *last << "nn";
trg.splice_after(trg.begin(), src, first, last);
cout << "Target after splice:n";
dump_list(trg);
cout << "Source after splice:n";
dump_list(src);
cout << endl;
return 0;
}
输出:first = 1, last = 4
Target after splice:
a 2 3 b c
Source after splice:
1 4
在forward_list的情况下,如何使范围splice_after常量时间?在源列表中,只有迭代器。要从源转发链表中删除节点,需要在last
之前的节点,因此需要在源中线性搜索该链表节点。因此,为什么first
和last
之间的距离是线性的
使用整个源列表的版本仍然需要在源结束之前立即搜索节点,以便可以将其修改为指向目标中拼接之后的元素。所以它也需要源大小的线性时间
范围拼接是size
在以前的c++标准中不是常量时间的唯一原因。事实上,Sun CC编译器选择使size
时间为常数,而所有版本的splice
都是线性的。
拼接整个前向链表是线性的,因为你必须遍历你正在合并的链表,才能将它的最后一个节点链接回你正在拼接的链表。我不明白为什么范围拼接是线性的。
编辑:正如@Xeo指出的,基于范围的版本也需要线性时间,因为last
不包括在范围内,它需要从first
搜索以找到 last
之前的迭代器。
- 重载运算符的范围是什么?它是否会影响作为类成员的集合的插入函数?
- 这个变量在 C++ 中的范围是什么?
- C++ 中的引用范围是什么?
- PTRACE_TRACEME的范围是多少?
- 确定范围是访问虚拟功能的合法方式吗?
- C 中类声明的范围是什么?
- C 中静态声明的结构的范围是什么?
- 这个无锁数据列表插入是安全的吗
- Winsock中插座对象的范围是什么?
- 默认模板参数的范围是什么?
- 封闭环变量的生存期和范围是什么
- 从 boost::algorithm::join 返回值的范围是什么?
- 类模板中定义的朋友函数范围定义的范围是什么?
- 在类方法中使用新运算符动态分配内存的寿命和范围是多少
- C/C++ main 函数中的参数列表大小是多少,行为不确定
- 错误:“列表”不是“std”的成员,错误:模板参数 2 无效
- 尝试将引擎从SDL重写为SFML,sf::RenderWindow的范围是错误的
- 功能范围是什么意思
- 可视化 C++ 宏重定义的范围是什么
- 为什么对std::forward_list拼接整个列表或范围是线性的?