【问题标题】:O(1) worst case append only arrayO(1) 最坏情况仅追加数组
【发布时间】:2021-04-20 01:21:40
【问题描述】:

我正在寻找一种支持 O(1) 随机访问和最坏情况 O(1) 追加的数据结构。 然而,在我的情况下,追加的 O(1) 摊销时间是 不是 我正在寻找的。​​p>

除了追加访问之外,数据结构也将不会对其执行任何操作。没有删除,没有插入,只是一个只能追加的结构

在我的例子中,上限会非常大,可能是 8GB。

此外,这个问题与 this 基本相同,但是,我对这个问题的答案的问题是它降低了内存分配的成本。 c++ 中的内存分配大部分时间是 O(1),但是,我经历过很多次 malloc 需要很长时间。

我想知道这样的结构是否甚至可以存在。我读了this pdf,但是我相信最坏情况下的时间复杂度仍然是O(1) amortized。

如果有人对可以支持这些条件的结构有任何想法(不是在寻找实现,只是一个想法),我们将不胜感激。

【问题讨论】:

  • 一个同样有效的问题是这样的结构是否存在?
  • 是的,这将是一个同样有效的问题
  • 您对尺寸有什么限制?有上限吗?是否有合理预期的元素数量?所有这些都是如何解决这个问题的考虑因素。
  • 就我而言,我认为它不会有上限,但可能会达到一定程度(例如 8GB)
  • 哎哟:)我问的原因是这个。如果您知道平均会有十亿个元素(在您的情况下),您可以通过预先分配预期数量的元素来降低分配成本。那时,您将拥有 O(1) 访问/附加,直到需要重新分配。然后知道你可能超出初始分配多少将允许一次重新分配来覆盖大多数情况。在大多数情况下,malloc 现在默认为 mmap,与过去相比,重新分配的成本也有所降低。

标签: c++ memory data-structures big-o


【解决方案1】:

std::deque 非常接近你想要的:

  1. O(1) 用于随机访问(是 std::vector 的两倍,因为它必须执行两次指针解引用,不仅仅是一次,而是像这样的固定倍数不会改变 big-O)
  2. 它实际上是O(1),而不仅仅是摊销O(1),如果你认为间歇性固定大小内存分配(没有初始化)是O(1)(它是;它不是固定成本,但成本是与deque的大小无关)

与链接问题中的分配不同(当新分配的内存大小翻倍,因此新分配呈线性增长时),std::deques 块分配是固定大小的,因此您可以:

  1. 将元素插入现有的分配空间,或
  2. 分配一个固定大小的块,然后将一个元素插入到新块的第一个槽中

由于新块的大小是固定的,而不是持续增长,它仍然是O(1)(有时是O(1 construction),有时是O(1 fixed size allocation + 1 construction),但仍然与deque的长度无关)。

【讨论】:

  • 你如何指定双端队列的固定缓冲区大小?例如,如果我有一个std::deque<char>,它的缓冲区大小是多少?
  • 但是,这个链接:stackoverflow.com/a/22307025/15699083 表明 std::deque 具有 O(1) 的附加时间复杂度。我认为这是真的,因为我相信 std::deque 在内部使用了 std::vector,并且增长是 O(1) 摊销
  • @CinCoutSinBla:该标准不允许您指定块大小(GCC 的实现曾经允许这样做,但当他们意识到它违反标准时将其删除)。它因实现而异,例如根据 cppreference,64 位 libc++ 的方法是块足够大,可容纳 16 个元素或 4096 字节,以较大者为准。
  • 嗯,好的。您是否看到我的评论以及关于摊销时间的链接?
  • 那个答案不正确。该标准规定了在std::deque 的开头或结尾插入的恒定时间,请参阅deque.modifiers
猜你喜欢
  • 2011-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-28
  • 1970-01-01
  • 2014-11-23
  • 2018-01-08
相关资源
最近更新 更多