【问题标题】:STL vector vs list: Most efficient for graph adjacency lists?STL 向量与列表:图邻接列表最有效?
【发布时间】:2011-07-23 09:04:46
【问题描述】:

在 push_back 时,列表会花费大部分时间来分配内存。另一方面,当需要调整大小时,向量必须复制它们的元素。因此,哪个容器最有效地存储邻接表?

【问题讨论】:

  • @quasiverse:vector 的要求基本上需要随着它的增长而复制。 vectors 需要连续存储它们的元素。当您添加元素时,您最终会用完分配的空间,并且在下一次添加时,您将获得新的内存分配,然后将当前元素复制到新空间,然后释放旧空间.

标签: c++ stl graph adjacency-list


【解决方案1】:

本教程网站建议使用列表数组,或者我想您可以使用列表元素的向量:array of lists adj list

【讨论】:

    【解决方案2】:

    您可以在此比较中添加第三个选项:带有专用分配器的列表。

    对固定大小的小对象使用分配器可以大大提高分配/解除分配的速度...

    【讨论】:

      【解决方案3】:

      我不认为可以绝对肯定地回答这个问题。尽管如此,我估计至少有 90% 的机会向量会做得更好。邻接列表实际上比许多应用程序更倾向于使用向量,因为邻接列表中元素的顺序(通常)并不重要。这意味着当你添加元素时,它通常在容器的末尾,而当你删除一个元素时,你可以先将它交换到容器的末尾,所以你只能在末尾添加或删除。

      是的,向量在扩展时必须复制元素,但实际上这几乎不是一个实质性的问题。特别是,向量的指数扩展率意味着元素被复制的平均次数趋向于一个常数——在典型的实现中,该常数约为 3。

      如果您的复制确实是一个真正的问题(例如,复制元素非常昂贵),那么我在 vector 之后的下一个选择仍然不会是 list。相反,我可能会考虑使用 std::deque 。它基本上是一个指向对象块的指针向量。它很少需要复制任何东西来进行扩展,而且在极少数情况下,它只需要复制指针,而不是对象。除非您需要双端队列的其他独特功能(在任一端以恒定时间插入/删除),否则向量通常是更好的选择,但即便如此,双端队列几乎总是比列表更好的选择(即向量通常是第一个选择,deque 紧随其后,最后列出很远)。

      【讨论】:

        【解决方案4】:

        STL 容器没有严格定义,因此实现方式各不相同。如果你很小心,你可以编写你的代码,这样它就不会关心它是一个正在使用的向量还是一个列表,你可以尝试它们来看看哪个更快。考虑到缓存效果等的复杂性,几乎不可能准确地预测相对速度。

        【讨论】:

          【解决方案5】:

          答案取决于用例。 附言@quasiverse - 当你“::reserve”的内存隐式或显式耗尽时,向量调用 realloc

          如果您有一个不断变化的邻接列表(插入和删除),最好使用列表。 如果您有一个或多或少的静态邻接列表,并且大部分时间都在进行遍历/查找,那么向量将为您提供最佳性能。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-06-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多