【发布时间】:2015-05-29 07:53:59
【问题描述】:
令 map 为 2D 哈希映射(有两个键),array 为 2D 动态数组。
我们可以说 map 比 array 占用更多的内存来存储信息吗? 我们可以说 map 在检索信息方面比 array 更快吗? 使用这两种数据结构中的任何一种是否还有其他优点和缺点?
【问题讨论】:
标签: multidimensional-array data-structures hashmap
令 map 为 2D 哈希映射(有两个键),array 为 2D 动态数组。
我们可以说 map 比 array 占用更多的内存来存储信息吗? 我们可以说 map 在检索信息方面比 array 更快吗? 使用这两种数据结构中的任何一种是否还有其他优点和缺点?
【问题讨论】:
标签: multidimensional-array data-structures hashmap
恐怕最好的答案是,“视情况而定”。
如果您将该二维数组视为空间分区 NxM 网格,就像哈希表一样,它可能非常稀疏(某些单元格将完全未被占用)。所以两者都可能浪费大量内存。
与哈希映射不同,我们不必将密钥对冗余存储到这样的二维结构中,因此可能会有一些潜在的好处。然而,这是一种不公平的比较,因为哈希集也不会,而且我们不一定需要具有键/值对的关联结构,只需要键。
在一天结束时,哈希表仍然是一维数据结构,因为您的密钥的配对方面是无关紧要的,除非在哈希函数中将其映射到一维位置。
在实践中,我发现二维分区网格的性能往往优于哈希表。这不是保证,因为涉及的因素太多(包括实施者的技能),但在“平均”情况下,它可能比哈希表略有优势。
主要原因是由于冲突:哈希表必须将这些键对映射到一维索引中,因此它更容易由于更多的冲突而降低性能,除非您的表非常稀疏(在这种情况下更多的内存, 更少的缓存命中也会降低性能等),或者除非您对这些密钥对只有出色的哈希函数。
2D 网格往往更容易提供更“稳定”的性能,而不会出现倾斜和降级。当您有许多 2D“点”位于同一个网格单元中时,它面临最坏的情况,理论上哈希表可能会解析为不同的桶,但通常比哈希表更容易避免这种情况和/或适应这种情况。由于不可预测的原因,可能会开始接收大量碰撞。但是,如果您使用 2D 网格,您通常希望通过链接方法(并且可能通过一些微优化来重新分配单元格中的元素以实现空间局部性)来涉及列表指针/引用,因为这种方法不太实用以这种方式解决冲突。
您确实可以通过 2D 网格获得更大的灵活性,例如最近邻搜索或搜索半径内的“点”。搜索不必是完全匹配的。
虽然哈希表有一个好处,在某些情况下可能会非常好。它不需要您提前了解您的钥匙的范围。使用网格,您必须提前知道您的密钥范围为[0,10000],例如哈希表可以处理(-inf,+inf) 范围,因此对于非常动态的场景可能非常有用,在这种场景中您无法预料到您提前插入的数据的任何内容。
【讨论】: