Data structures 是否有一个;金字塔列表“;数据结构已经存在吗?

Data structures 是否有一个;金字塔列表“;数据结构已经存在吗?,data-structures,database-design,embedded,Data Structures,Database Design,Embedded,我正在考虑可以在嵌入式/内存受限/文件系统等环境中使用的数据结构,并想出了一个类似列表的数据结构的想法,该结构具有O(1){access,insert,pop},同时始终具有O(1)push(非摊销),即使它只能以常量(即4KiB)增长。我在任何地方都找不到它的例子,我想知道它是否存在,如果存在,是否有人知道参考实现 基本结构如下所示: 金字塔列表包含 asize\u t numSlots a大小\u t大小地块 一个void**slots指针,指向大小为sizeSlots的指针数组,指针指向

我正在考虑可以在嵌入式/内存受限/文件系统等环境中使用的数据结构,并想出了一个类似列表的数据结构的想法,该结构具有O(1){access,insert,pop},同时始终具有O(1)push(非摊销),即使它只能以常量(即4KiB)增长。我在任何地方都找不到它的例子,我想知道它是否存在,如果存在,是否有人知道参考实现

基本结构如下所示:

金字塔列表包含

  • a
    size\u t numSlots
  • a
    大小\u t大小地块
  • 一个
    void**slots
    指针,指向大小为
    sizeSlots
    的指针数组,指针指向的索引中的值最多为
    numSlots
对于每个索引,
void**slots
数组具有以下结构。它们的结构应确保
2^i=maxValues
其中
i
是索引,而
maxValues
是该索引处可存在或小于该索引的最大值数(即,截至该索引的所有值的计数之和)

  • 索引0:包含直接指向单个值的指针(
    2^0=1
  • 索引1:包含直接指向单个值的指针(
    2^1=2
  • 索引2:包含指向两个值的数组的指针(
    2^2=4
  • 索引3:包含指向四个值的数组的指针(
    2^3=8
  • 索引4:包含指向八个值的数组的指针(
    2^4=16
  • 。。等
  • 索引M:包含指向MAX_NUM_值数组的指针(
    2^M=MAX_NUM_值*2
  • 索引M+1:包含指向最大值数组的指针
  • 索引M+2:包含指向最大值数组的指针
现在,假设我想访问索引
I
。我可以使用指令获得索引的“2的幂”。如果它小于MAX_NUM_值的2的幂,那么我有我的索引。如果它大于MAX_NUM_值的2的幂,我可以相应地采取行动(减法和除法)。因此,我可以在O(1)时间内查找数组/单个值,然后访问O(1)中所需的索引。推送到列表需要(最多):

  • 分配新的MAX_NUM_值并将其指针添加到
    插槽
    • 在某些情况下,
      slot
      可能无法容纳它,并且还必须进行扩展,因此这实际上总是O(1)到某个极限,但对于这里的用例来说,该极限可能是极端的
  • 将值插入到适当的索引中
其他一些好处
  • 适用于具有最大alloc大小(即只能分配4KB块)的内存管理器(嵌入式/文件系统/内核/etc)
  • 当你真的不知道你的向量可能有多大的时候,这个方法非常有效。开始时非常小,并以已知数量增长
  • 始终保持(接近)恒定插入对于定时关键中断/等可能有用
  • 成长时不会留下碎片化的空间。将记录追加到文件中可能非常有用
缺点 几乎在所有方面(甚至插入)都可能不如连续向量的性能(摊销)。移动内存通常比为每个操作添加解引用要便宜,因此向量的摊余成本可能仍然更小


另外,它并不总是O(1),因为当所有插槽都已满时,必须增加
插槽
向量,但这只发生在自上次增长以来已添加
currentNumSlots*2*MAX_NUM_值的情况下。

当超过大小为X的数组的容量,并因此分配大小为2X的新数组时,然后,您可以在接下来的X追加操作中将X项从旧数组增量移动到新数组的开头。在这之后,当新数组已满时,旧数组可以被丢弃,就在您必须分配一个大小为4X的新数组之前

因此,为了实现O(1)个追加(假设分配为O(1)),不必维护这个不断增大的数组列表。增量倍增是去摊销业务中的一项众所周知的技术,因此我认为大多数希望这种行为的人会首先求助于此


没有像这样的东西是常用的,因为内存分配几乎永远不会被认为是O(1)。不能同时复制一个块的应用程序通常根本不能使用任何类型的动态内存分配。

此结构与数组之间的区别是什么?据我所知,阵列将呈现相同的功能。即使没有有效的内存分配(即一次只能增长1页),也始终是O(1)增长是的,我知道阵列重新分配通常是如何工作的。请注意,重点不是“增加大小”数组,而是数组大小有一个上限。内存分配缓慢是一个好问题——如果没有快速的内存块源,这将是无用的。