【问题标题】:Data Structure that introduces data like a stack, and stores in buckets like a hashtable?像堆栈一样引入数据并像哈希表一样存储在桶中的数据结构?
【发布时间】:2025-12-25 13:50:07
【问题描述】:

我需要一种像堆栈一样引入数据的算法,因此当我扫描结构时,我可以按照引入它们的顺序读取它们,以进行顺序访问。这些值也存储在存储桶中,例如哈希表,因此我可以将整个结构分段用于磁盘存储并进行快速随机访问。

是否有这样的算法,或者我应该有两个独立的结构?最好的策略是什么?

最好的问候!

【问题讨论】:

    标签: data-structures stack hashtable


    【解决方案1】:

    我可能会这样做:

    1. 创建一个您实际存储条目的哈希表
    2. 创建一个堆栈来存储对象的真实内存位置(而不是对象本身)
    3. 将这两个结构抽象到一个类(或类似的东西)后面,以便对用户隐藏它的真正实现。

    【讨论】:

    • 另外,正如詹姆斯指出的那样,您似乎实际上是在谈论队列,但这并没有改变我实现事物的方式。
    • 在我的帖子中指出,从哈希图中删除没有键的对象不是 o(1)(在执行 stack.pop() 操作时),并且从堆栈(在执行 hashmap.remove(key) 操作时)也不是 o(1)。这使得任何删除都会对两种数据结构都造成不利影响,而不会带来任何好处。但是 get/peeks 和 put/push 将不受影响。
    【解决方案2】:

    这有点像有序地图,对吧?这些通常是通过将链表与您想要用来实现映射的任何内容(例如哈希表)组合来实现的。

    在 Ruby 1.9 中,Hash 类的规范(Ruby 拼写“Map”的方式令人困惑)已更改,以便保留插入顺序。我知道的大多数 Ruby 1.9 实现都将其实现为列表和哈希表的某种组合。 Rubinius 的实现特别容易阅读,因为它是 100% 用 Ruby 编写的:kernel/common/hash.rb

    Java 有一个有序映射的实现,称为LinkedHashMap。以下是 Oracle OpenJDK 7 的源代码:/share/classes/java/util/LinkedHashMap.java

    Apache Commons Collections 有一个OrderedMap 接口和两个实现:LinkedMapListOrderedMap

    如果你稍微小心一点,你应该能够保持无序映射的渐近复杂度保证。

    【讨论】:

      【解决方案3】:

      首先,我认为您的意思是“像队列一样引入数据”。堆栈将以与输入相反的顺序返回数据。 (另外,我不确定您所说的“引入数据”是什么意思 --- 我不确定这是语言问题,还是我从未听说过的数据结构表达式)。

      我的建议是使用侵入式链接列表(链接存储在数据对象中)来创建您的线性列表。然后,您可以将数据对象(附有链接)放入哈希表中。

      【讨论】:

        【解决方案4】:

        like stargazer 指出具有两种数据结构的抽象类是一种方法。不过也有一些注意事项。

        1. 当你弹出一个值时,你还会有它的键吗?如果不是,那么从哈希图中将其删除将是一项艰难的操作(不是 O(1))。如果这将是获取数据的主要模式,也许值得将每个对象都保留在该对象中。

        2. 当您从表中删除一个值时,您还必须将其从列表中删除。也许值得将对象 ListNode 保留在对象中,以便从堆栈/队列中移除 O(1)。

        如果一种移除方法占主导地位,则可能很容易采取上述处罚之一。

          1234563抽象方法有效。 1234563 >
        1. 如果您希望 hashmap 存储所有内容(从不删除数据),但保留一个单独的队列/堆栈进行处理(仅删除数据),那么抽象将是完美的。

        但是,如果这些都不是,并且您无法更改对象(以强制它实现您的缓存方案),则意味着您必须自己缓存这两个值(对象键和列表节点)。它为您的抽象类引入了第三种数据结构。在这一点上,您必须问自己,这种抽象方法是否值得?在那些数据将被同等地(或不可预测地)删除的情况下,那么值得做一些预先准备好的事情,ala jorg mittag。我相信那些实现是直接的哈希图,但是每个哈希节点也有一个像列表一样的上一个和下一个链接,并且哈希图本身有一个尾部和头部。 (用于堆栈/队列,如弹出/推送)

        基本上归结为您将如何使用此数据结构。如果不详细说明所有方法的调用方式和用例,则任何算法都不能被视为最佳策略。

        【讨论】: