我提出了一种数据结构,它结合了链表的一些优点和固定大小数组的一些优点。这对我来说似乎非常明显,所以我希望有人能够想到它并将其命名。有谁知道这叫做什么:
采用小型固定大小的阵列。如果要放入数组中的元素数量大于数组的大小,请在新旧数组之间添加一个新数组以及您喜欢的任何指针。
因此你有:
Static array
—————————————————————————
|1|2|3|4|5|6|7|8|9|a|b|c|
—————————————————————————
Linked list
———— ———— ———— ———— ————
|1|*->|2|*->|3|*->|4|*->|5|*->NULL
———— ———— ———— ———— ————
My thing:
———————————— ————————————
|1|2|3|4|5|*->|6|7|8|9|a|*->NULL
———————————— ————————————
编辑:作为参考,此算法提供相当差的最差情况下的添加/删除性能,并且平均情况不是更好。我的方案的一大优势是提高了读取操作的缓存性能。
编辑赏金:Antal S-Z的答案是如此完整和精心研究,我想为他们提供赏金。显然Stack Overflow不让我接受答案,一旦我提供赏金,所以我将不得不等待(诚然,我有点滥用意图赏金系统,虽然这是为了奖励某人的优秀回答)。当然,如果有人 设法提供更好的答案,给他们更多的权力,他们肯定会获得赏金!
编辑重新命名:我对你所谓的内容不感兴趣,除非你打电话给它,因为那是主题上的权威人士所称之为它。如果这是你想出的名字,我不感兴趣。我想要的是一个名字,我可以在教科书和谷歌中查找。 (另外,这里有一个提示:Antal的答案就是我所寻找的。如果你的答案不是“展开的链表”而没有非常的理由,那就完全错了。)
答案 0 :(得分:23)
它被称为unrolled linked list。似乎有一些优势,一个是速度,一个是空间。首先,如果每个节点中的元素数量大小合适(例如,最多只有一个缓存行的大小),则从改进的内存位置可以获得明显更好的缓存性能。其次,因为你有O( n / m )链接,其中 n 是展开的链表中的元素数量和 m 是您可以在任何节点中存储的元素数量,您还可以节省大量空间,如果每个元素都很小,这一点尤为明显。在构建展开的链表时,显然实现会尝试在节点中留出空间;当您尝试插入完整节点时,将一半元素移出。因此,最多一个节点将小于半满。根据我能找到的东西(我自己没有做过任何分析),如果你随机插入东西,节点往往实际上大约四分之三满,或者如果操作往往在列表的末尾则更加丰富。
正如其他所有人(包括维基百科)所说,你可能想看看skip lists。跳过列表是一种漂亮的概率数据结构,用于存储具有插入,删除和查找的O(log n )预期运行时间的有序数据。它由链表的“塔”实现,每个层的元素越少,它就越高。在底部,有一个普通的链表,包含所有元素。在每个连续层,元素数量较少,因子为 p (通常为1/2或1/4)。它的构建方式如下。每次将一个元素添加到列表中时,它都会插入到底行的适当位置(这使用“查找”操作,也可以快速进行)。然后,以概率 p ,将其插入到“上方”链表中的适当位置,如果需要则创建该列表;如果它被放置在更高的列表中,那么它将再次以 p 的概率出现在上面。要查询此数据结构中的内容,请始终检查顶部通道,并查看是否可以找到它。如果您看到的元素太大,则会下降到下一个最低的泳道并再次开始查看。这有点像二元搜索。维基百科很好地解释了它,并且有很好的图表。当然,内存使用情况会更糟,并且您不会获得改进的缓存性能,但通常会更快。
答案 1 :(得分:3)
CDR coding(如果你已经足够老了,可以记住Lisp Machines)。
另见ropes,这是字符串列表/数组想法的概括。
答案 2 :(得分:1)
我称之为桶清单。
答案 3 :(得分:1)
虽然我不知道您的任务,但我强烈建议您查看跳过列表。
至于名字,我认为一个桶清单可能是最合适的
答案 4 :(得分:0)
您可以将其称为LinkedArrays
。
另外,我希望看到removeIndex
操作的伪代码。
答案 5 :(得分:0)
此数据结构在插入和删除方面有哪些优势? 例如: 如果要添加3到4之间的元素,该怎么办?还是要换班,需要O(N) 你如何找到elementAt的正确存储桶?
我同意jer,你必须看看跳过列表。它带来了Linked List和Arrays的优点。 大多数操作都是在O(log N)
中完成的