数百万随机无序密钥的复杂度为O(1)的Java密钥值集合

时间:2014-02-13 14:09:53

标签: java data-structures hashmap time-complexity keyvaluepair

我遇到了一个问题,即我需要随机使用密钥(而不是使用迭代器)来访问数百万个键值对。

在编译时不知道键的范围,但键值对的总数是已知的。

我已经研究过 HashMap Hashset 数据结构,但它们并不是真正的 O(1),就像哈希中的碰撞一样-code它们成为 LinkedLists 的数组,在最坏的情况下具有线性搜索复杂性。

我还考虑在 HashMap 中增加存储桶的数量,但不能确保每个元素都存储在一个单独的存储桶中。

有没有办法以 O(1)复杂度存储和访问数百万个键值对?

理想情况下,我希望每个键都像变量一样,相应的值应该是分配给该键的值

提前致谢。

2 个答案:

答案 0 :(得分:1)

不,通用数据类型没有这种(已知的)数据结构。

如果有的话,它很可能已经替换了大多数常用库中的哈希表,除非有一些显着的缺点,如大量的常数因子或荒谬的内存使用,这两种情况都可能使它对你来说也不可行。

我上面说过“通用数据类型”,因为可能存在一些特定的特殊情况,例如当键是小范围内的整数时 - 在这种情况下,你可以只有一个数组,其中每个索引对应于相同的键,但这实际上也是一个哈希表,其中键是哈希值。


请注意,您需要一个糟糕的哈希函数,哈希函数的pathological输入,或者一个非常小的哈希表,以实际获得哈希表的最坏情况O(n)性能。在你去寻找别的东西之前,你真的应该测试一下它是否足够快。您也可以尝试TreeMap,它的O(log n)操作有时会优于HashMap

答案 1 :(得分:1)

我认为你对Big O符号所代表的东西感到困惑。它定义了函数的限制行为,而不一定是实际行为。

对于插入,删除和搜索操作,哈希映射的平均复杂度为O(1)。这是什么意思?平均而言,无论哈希映射的大小如何,这些操作平均都将在恒定时间内完成。因此,根据地图的实现,查找可能不会只采取一步,但相对于哈希映射的大小,它很可能不会涉及多个步骤。

哈希映射对这些操作的实际行为有多好,取决于几个因素。最明显的是用于桶密钥的哈希函数。哈希函数在哈希范围内更均匀地分布计算的哈希值,并且优先限制冲突的数量。这些区域中的哈希函数越好,哈希映射将在恒定时间内实际运行得越近。

影响实际哈希映射行为的另一个因素是如何管理存储。在添加和删除项目时,地图如何调整大小和重新定位条目有助于通过使用最佳数量的桶来控制哈希冲突。有效地管理哈希映射存储将允许哈希映射在接近恒定时间内运行。

尽管如此,有一些方法可以构造具有O(1)最坏情况行为的哈希映射。这是使用perfect hash function完成的。完美的哈希函数是键和哈希之间的可逆1-1功能。利用完美的散列函数和适当的散列映射存储,可以实现O(1)查找。使用这种方法的先决条件是提前知道所有关键值,这样就可以开发出完美的哈希函数。

可悲的是,你的案例并不涉及已知的密钥,因此无法构建完美的哈希函数,但是,可用的研究可能会帮助你为你的案例构建一个接近完美的哈希函数。