【发布时间】:2025-12-25 13:50:07
【问题描述】:
我需要一种像堆栈一样引入数据的算法,因此当我扫描结构时,我可以按照引入它们的顺序读取它们,以进行顺序访问。这些值也存储在存储桶中,例如哈希表,因此我可以将整个结构分段用于磁盘存储并进行快速随机访问。
是否有这样的算法,或者我应该有两个独立的结构?最好的策略是什么?
最好的问候!
【问题讨论】:
标签: data-structures stack hashtable
我需要一种像堆栈一样引入数据的算法,因此当我扫描结构时,我可以按照引入它们的顺序读取它们,以进行顺序访问。这些值也存储在存储桶中,例如哈希表,因此我可以将整个结构分段用于磁盘存储并进行快速随机访问。
是否有这样的算法,或者我应该有两个独立的结构?最好的策略是什么?
最好的问候!
【问题讨论】:
标签: data-structures stack hashtable
我可能会这样做:
【讨论】:
这有点像有序地图,对吧?这些通常是通过将链表与您想要用来实现映射的任何内容(例如哈希表)组合来实现的。
在 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 接口和两个实现:LinkedMap 和ListOrderedMap。
如果你稍微小心一点,你应该能够保持无序映射的渐近复杂度保证。
【讨论】:
首先,我认为您的意思是“像队列一样引入数据”。堆栈将以与输入相反的顺序返回数据。 (另外,我不确定您所说的“引入数据”是什么意思 --- 我不确定这是语言问题,还是我从未听说过的数据结构表达式)。
我的建议是使用侵入式链接列表(链接存储在数据对象中)来创建您的线性列表。然后,您可以将数据对象(附有链接)放入哈希表中。
【讨论】:
like stargazer 指出具有两种数据结构的抽象类是一种方法。不过也有一些注意事项。
当你弹出一个值时,你还会有它的键吗?如果不是,那么从哈希图中将其删除将是一项艰难的操作(不是 O(1))。如果这将是获取数据的主要模式,也许值得将每个对象都保留在该对象中。
当您从表中删除一个值时,您还必须将其从列表中删除。也许值得将对象 ListNode 保留在对象中,以便从堆栈/队列中移除 O(1)。
如果一种移除方法占主导地位,则可能很容易采取上述处罚之一。
如果您希望 hashmap 存储所有内容(从不删除数据),但保留一个单独的队列/堆栈进行处理(仅删除数据),那么抽象将是完美的。
但是,如果这些都不是,并且您无法更改对象(以强制它实现您的缓存方案),则意味着您必须自己缓存这两个值(对象键和列表节点)。它为您的抽象类引入了第三种数据结构。在这一点上,您必须问自己,这种抽象方法是否值得?在那些数据将被同等地(或不可预测地)删除的情况下,那么值得做一些预先准备好的事情,ala jorg mittag。我相信那些实现是直接的哈希图,但是每个哈希节点也有一个像列表一样的上一个和下一个链接,并且哈希图本身有一个尾部和头部。 (用于堆栈/队列,如弹出/推送)
基本上归结为您将如何使用此数据结构。如果不详细说明所有方法的调用方式和用例,则任何算法都不能被视为最佳策略。
【讨论】: