快速数据结构,支持查找最小元素以及访问,插入,删除和更新任何索引处的数据

时间:2015-04-12 01:39:04

标签: c++ data-structures

我正在寻找实现模板化序列容器数据结构的想法,该数据结构可以在尽可能多的功能中击败std::vector的性能并且可能执行得更快。它应该支持以下内容:

  • 查找最小元素(并返回其索引)
  • 在任何索引处插入
  • 删除任何索引
  • 按索引(通过operator[]
  • 访问和更新任何元素

在C ++中实现这样的结构有什么好方法?

1 个答案:

答案 0 :(得分:2)

您通常非常确定所有容器的STL实现在其设计的任务范围内往往非常好。也就是说,您不太可能构建一个与std::vector一样健壮且对所有应用程序都更快的容器。但是,一般来说,在优化特定应用程序时,几乎总是可以击败通用工具。

首先,让我们考虑vector实际上是什么。您可以将其视为指向c-style array的指针,除了它的元素存储在堆上。与c数组不同,它还提供了一系列方法,使操作更方便。但是像c-array一样,它的所有数据都是连续存储在内存中的,因此查找非常便宜,但是改变它的大小可能需要将整个数组转移到内存中的其他地方为新元素腾出空间。

以下是一些关于如何处理更好而不是香草std::vector的事情的想法:

  1. 查找最小元素:对于许多容器,搜索通常为O(N),对于vector,搜索通常为O(1)(因为您需要迭代所有元素以找到最低的元素) 。您只需保留最小的元素,并且只在更改容器时更新它,就可以使它boost或非常接近自由。
  2. 在任何索引处插入:如果你的元素很小而且数量不多,我就不会在这里修补,只需做矢量所做的事情并保持元素彼此相邻保持快速查找。如果您有大元素,则存储指向元素的指针而不是元素本身(std::vector的稳定向量将为您执行此操作)。请记住,这会使查找更加昂贵,因为您现在需要取消引用指针,因此您是否要这样做取决于您的应用程序。如果您知道要插入的元素数量,reserve会提供push_back方法为您预先分配一些内存,但做的是允许您决定分配的内存的大小如何增长。因此,如果您的应用程序保证大量reserve操作没有足够的信息来智能地调用std::vector,那么您可以通过定制容器的the growth function来超越标准std::vector实施你的特殊需求。另一种选择是使用链接列表(例如std::list),它将在更大容​​器的插入中击败O(N)。但是,这里的成本是查找(参见4.)现在变得非常慢(向量为O(1)而不是std::vector),因此您不太可能想要沿着这条路走下去,除非你计划进行比查找更多的插入/擦除。
  3. 删除任何索引:与2相似的注意事项。
  4. 按索引访问和更新任何元素(通过operator []):在这方面,唯一可以击败boost的方法是确保您的数据在缓存中试着访问它。这是因为向量的查找本质上是一个数组查找,它实际上只是一些指针算法和一个指针解除引用。如果您不经常访问您的矢量,那么可能能够通过使用自定义分配器(请参阅std::vector池)并将您的池放在靠近的位置来挤出几个时钟周期stack pointer
  5. 我停止写作主要是因为有很多方法可以解决这个问题。

    在一天结束时,这可能更像是一种教你的工作,{{1}}的实现可能对大多数编译器来说非常有效。所有这些建议基本上都是微观优化(the root of all evil),所以请不要在重要的代码中盲目地应用这些建议,因为他们很可能最终花费你很多时间和头痛。

    但是,并不是说你不应该为自己修补和学习,所以一定要继续尝试为你的应用程序打败它,让我们知道你的进展!祝你好运:)