algorithm - 缓存无关堆栈和队列的复杂性

标签 algorithm cache-oblivious

我读到可以使用加倍数组来实现缓存不经意堆栈。

有人可以解释分析如何使每次推送和弹出都具有 1/B 摊销 I/O 复杂度吗?

最佳答案

栈支持以下操作:

  • 推送
  • 流行

虽然这两个操作可以使用具有 O(1) push 和 O(1) pop 的单链表来执行,但它会遇到缓存问题,因为存储的元素分散在内存中。对于这种方法,我们推到列表的前面,然后从列表的前面弹出。

我们可以使用 dynamic array作为我们的数据结构,插入和弹出到数组的末尾。 (我们将跟踪数组中最后填充的位置作为我们的索引,并在我们压入和弹出元素时修改它)。

弹出的时间复杂度为 O(1),因为我们不需要调整数组的大小。

如果数组末尾有多余的空间,则插入O(1)。

问题是当我们试图压入一个元素但没有空间容纳它时。在本例中,我们创建了一个两倍大 (2n) 的新数组,然后将 n 个元素中的每一个复制过来,然后压入该元素。

假设我们有一个大小为 n 的数组,但开始时为空。

如果我将 n+1 个元素压入数组,那么前 n 个元素需要 O(1)*n = O(n) 的时间。

+1 元素需要 O(n) 时间,因为它必须构建数组的新副本。

所以将 n+1 个元素插入数组是 O(2n),但我们可以去掉常量,只说它是 O(n) 或元素数量的线性。

因此,虽然推送单个元素可能比持续操作花费更长的时间,但推送大量元素需要线性工作量。

动态数组是缓存友好的,因为所有元素都尽可能靠近,所以多个元素应该在相同的缓存行中。

关于algorithm - 缓存无关堆栈和队列的复杂性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12135640/

相关文章:

windows - 如何比较文件列表的大小并取最大的?

algorithm - 内存有限时位图编辑器的快速撤消/重做?

c - 分而治之矩阵的就地转置

algorithm - 用于并行编程的缓存不经意算法?

algorithm - 如何使用 van Emde Boas 布局计算二叉树中的指针

algorithm - 排序多边形的点

algorithm - 超分辨率和拉普拉斯项

algorithm - 如何在动态规划算法中进行转换?