为什么我们需要链表?
链表是 O(1) 的插入、删除、连接等。链表变大了吗?那又怎样,系统保持正常运行。只是计划不需要随机访问。
向量以(可能)二进制块的形式增长,因此时间命中增长到相当大且相当快的东西。这是一个公认的罕见的时间点击。
在 Ubuntu-15.04 上的旧戴尔 g++ 4.9.2 的以下输出中,最后一列是自上次容量更改以来的毫秒时间。 (最后一列匆忙添加,以便为您重复使用示例;)
element vector bytes stack use bytes heap use
count capacity 'sizeof(vector)' (element count * element size)
0 0 24 0 0
1 1 24 4 0
2 2 24 8 0
3 4 24 12 0
5 8 24 20 0
9 16 24 36 0
17 32 24 68 0
33 64 24 132 0
65 128 24 260 1
129 256 24 516 0
257 512 24 1,028 0
513 1,024 24 2,052 0
1,025 2,048 24 4,100 0
2,049 4,096 24 8,196 0
4,097 8,192 24 16,388 1
8,193 16,384 24 32,772 2
16,385 32,768 24 65,540 3
32,769 65,536 24 131,076 8
65,537 131,072 24 262,148 12
131,073 262,144 24 524,292 28
262,145 524,288 24 1,048,580 50
524,289 1,048,576 24 2,097,156 38
1,048,577 2,097,152 24 4,194,308 76
2,097,153 4,194,304 24 8,388,612 149
4,194,305 8,388,608 24 16,777,220 300
8,388,609 16,777,216 24 33,554,436 601
16,777,217 33,554,432 24 67,108,868 1215
33,554,433 67,108,864 24 134,217,732 2475
67,108,865 134,217,728 24 268,435,460 4982
134,217,729 268,435,456 24 536,870,916 10247
268,435,457 536,870,912 24 1,073,741,828 21387
这是足够的理由吗?我不知道。
我将向量用于我的列表(它几乎永远不会增长到 Gigabyte 大小,当我找到最大大小时我添加了 Reserve 的使用)、我的 fifo(处理文件和目录创建了数百万个字符串),并且通常忽略这个列表,因为我使用向量的速度足够快(哎呀,不敢相信我刚刚大声说出来)。
此表中的最后一个条目是当向量容量增加到 512 K 元素时(从 512 K - 1)。分配、数据复制和擦除(使用小对象的 noop dtors)但没有更多的 push_back()s,导致堆栈上的 1 G 字节,耗时 21 秒。
(我想我不再希望在这台旧机器上安装 8 Gig。)
编辑 - 2015 年 7 月 1 日
我重新运行此代码以重新生成表格的最后 2 行并捕获挂钟信息。
134,217,729 268,435,456 24 536,870,916 9769
268,435,457 536,870,912 24 1,073,741,828 20983
real 0m41.147s
user 0m39.928s
sys 0m1.164s
挂钟时间报告为 41 秒。
产生最后一条输出线需要 21 秒(以毫秒为单位的实时时钟测量),并且
20 秒产生第 1 29 行...这不只是指数!
编辑 - 2015 年 7 月 3 日 - 认为 OP 需要一些关于集合与链表的 cmets。
如果我们有可以动态增长和收缩的 std::set [and ...],为什么
我们需要链表吗?
来自 cppreference.com:
std::set 是一个关联容器,它包含一个排序的集合
Key 类型的唯一对象。排序是使用键比较完成的
功能比较。搜索、删除和插入操作
对数复杂度。集合通常实现为红黑
树。
一方面,集合(我很少使用)有点像链表,其中会有节点(当实现为红黑树时),每个节点都是独立分配的。当集合变大时,系统会保持相对正常的运行(始终如一?)(至少在节点涉入交换之前(我说的是交换,不是沼泽)。
恕我直言,一个集合(rbtree)没有“工作积压”。相反,树在每次插入/追加/删除工作上取得平衡。 (我无法通过一点点努力来挑逗一些证据......对不起,没有桌子可以看。)
当您查看红黑树时,您会发现 rbtree 不包含数据,只有键(和颜色)。
我可以想象一个链表,其中只有数据中的键和颜色(如集合)。软件非常灵活。但我的想象力现在失败了。
我非常欣赏关联容器的想法。我发现 std::map 非常有用,它影响了我对几种软件挑战的看法。
但是,我还没有研究过这张地图是如何发挥它的魔力的。多学习。