在push_back中,列表占用大部分时间来分配内存。另一方面,当需要调整大小时,向量必须复制它们的元素。因此,哪个容器最适合存储邻接列表?
答案 0 :(得分:13)
我认为不能绝对肯定地回答这个问题。尽管如此,我估计一个载体至少有90%的可能性会更好。邻接列表实际上倾向于支持向量而不是许多应用程序,因为邻接列表中的元素顺序(通常)不重要。这意味着当你添加元素时,它通常是在容器的末尾,当你删除一个元素时,你可以先将它交换到容器的末尾,所以你只能在最后添加或删除。
是的,矢量必须在扩展时复制元素,但实际上这几乎不是一个重要的问题。特别是,向量的指数扩展率意味着元素被复制的平均次数倾向于常数 - 在典型的实现中,该常量约为3.
如果您处理的情况是真正的复制是一个真正的问题(例如,复制元素非常昂贵),我在矢量后的下一个选择仍然不会是列表。相反,我可能会考虑使用std :: deque。它基本上是指向对象块的指针向量。它很少需要复制任何东西来进行扩展,并且在罕见的情况下,它必须复制的只是指针,而不是对象。除非你需要deque的其他独特功能(在两端的常量时间内插入/删除),矢量通常是更好的选择,但即使如此,deque几乎总是比列表更好的选择(即,矢量通常是第一个选择,deque一个相当接近的第二个,并列出相当遥远的最后一个。)
答案 1 :(得分:1)
答案取决于用例。 附: @quasiverse - 当你“隐藏或明确地”存储的内存耗尽时,向量调用realloc
如果您有不断变化的邻接列表(插入和删除),则列表最佳。 如果您有一个或多或少的静态邻接列表,并且大多数时候您正在进行遍历/查找,那么向量将为您提供最佳性能。
答案 2 :(得分:0)
STL容器没有严格定义,因此实现方式各不相同。如果你小心,你可以编写你的代码,这样它就不关心它是一个向量还是一个正在使用的列表,你可以试着看看哪个更快。鉴于缓存效果等的复杂性,几乎不可能以任何精度预测相对速度。
答案 3 :(得分:0)
您可以为此比较添加第三个选项:带有专门分配器的列表。
对固定大小的小对象使用分配器可以大大提高分配/释放的速度......
答案 4 :(得分:0)
此教程站点建议使用列表数组,或者我想您可以使用列表元素的向量代替:array of lists adj list