哈希表有什么意义?

时间:2010-02-01 20:49:03

标签: hashtable

我没有动态语言中数组/字典之外的哈希表的经验,所以我最近发现内部它们是通过创建密钥的哈希并使用它来存储值来实现的。我不明白的是,为什么不将键(字符串,数字等)存储的值作为键,而不是存储它的哈希并存储它。

11 个答案:

答案 0 :(得分:10)

这是近似重复:Why do we use a hashcode in a hashtable instead of an index?

简而言之,您可以非常快速地检查密钥是否已经存储,并且同样快速地存储新映射。否则你必须保留一个排序的密钥列表,这对于存储和检索映射要慢得多。

答案 1 :(得分:8)

  

我不明白为什么不将密钥(字符串,数字,等等)存储的值作为密钥

你是如何实现的?

计算机只知道数字。哈希表是一个,即一个数组,当我们接下来时,一个数组只能通过一个非整数的非负索引 。其他一切都是骗局。允许您使用字符串键的动态语言 - 它们使用技巧。

一个这样的技巧,通常是最优雅的,只是计算密钥的数字,可重现的“哈希”数,并将其用作索引。

(还有其他考虑因素,例如压缩关键范围,但这是最重要的问题。)

答案 2 :(得分:5)

什么是哈希表

它也被称为哈希映射是用于实现关联数组数据结构。它是一个可以映射键的结构价值观。

如何运作?

哈希表使用哈希函数来计算桶或槽数组的索引,从中可以找到正确的值。

见下图清楚解释。

enter image description here

<强>优点:

在尺寸合适的哈希表中,每次查找的平均成本与表中存储的元素数量无关。

许多哈希表设计还允许任意插入和删除键值对。

在许多情况下,哈希表比搜索树或任何其他表查找结构 更高效

<强>缺点:

当条目数非常小时,哈希表无效。 (但是,在某些情况下,可以通过将哈希值与密钥一起保存来减轻计算哈希函数的高成本。)

<强>用途:

它们广泛用于多种计算机软件,特别是关联数组,数据库索引,缓存和集合。

答案 3 :(得分:2)

哈希表的想法是提供对其项目的直接访问。这就是为什么它计算密钥的“哈希码”并使用它来存储密钥本身的项目。

这个想法是每个键只有一个哈希码。很多时候,生成哈希码的哈希函数是划分素数并使用其格式作为哈希码。

例如,假设您有一个包含13个位置的表,并且有一个整数作为键,因此您可以使用以下哈希函数

f(x)= x%13

答案 4 :(得分:1)

通常,散列表的要点是存储一些稀疏值 - 即存在大的键空间和少量要存储的东西。想想字符串。有无数可能的字符串。如果要存储程序中使用的变量名,那么即使您事先并不知道它们是什么,但实际使用的字符串数量相对较少。

答案 5 :(得分:1)

  

我不明白为什么不是   使用密钥存储的值   (字符串,数字,等等)作为,   好吧,关键,而不是哈希   它并存储它。

嗯, 你打算用O(1)查找做什么?

哈希表的基本点是通过将密钥转换为数组索引然后在该索引处返回数组的内容来提供O(1)查找。为了实现您需要的任意键

  1. 将密钥转换为数组索引的方法(这是哈希的目的)
  2. 处理冲突的方法(具有相同哈希码的密钥)
  3. 当数组太小(导致太多碰撞)或太大(浪费空间)时调整数组大小的方法

答案 6 :(得分:1)

简而言之:Hashing允许对表进行O(1)查询/插入/删除。 OTOH,一个排序结构(通常实现为平衡BST)使相同的操作花费O(logn)时间。

为什么要拿哈希?您如何建议将钥匙存储为“钥匙”?问问自己,如果您计划存储简单(键,值)对,您的查找/插入/删除速度有多快?你会在整个数组/列表上运行O(n)循环吗?

具有哈希值的重点在于它允许将所有键转换为有限的哈希值集。这允许我们将密钥存储在有限数组的插槽中(启用快速操作 - 而不是搜索整个列表,您只搜索具有相同散列值的那些键),即使可能的密钥集可能非常大或无限(例如,密钥可以是字符串,非常大的数字等。)使用良好的散列函数,很少有密钥具有相同的散列值,并且所有操作实际上都是O(1)。

如果您不熟悉散列以及散列表的工作方式,这可能没什么意义。在这种情况下最好的做法是参考一本好的算法/数据结构书的相关章节(我推荐CLRS)。

答案 7 :(得分:0)

在某些情况下,密钥可能很长或很大,因此保留这些密钥的副本是不切实际的。首先散列它们可以减少内存使用量并缩短查找时间。

答案 8 :(得分:0)

哈希表用于存储一组值及其键(在一段时间内)常数个点。在一个简单的例子中,假设你想使用i%10的​​哈希函数保存0到10000之间的每个整数。

这将产生1000个块(通常是数组)的哈希表,每个块具有10个元素深度的列表。因此,如果您要搜索1234,它会立即知道在表条目中搜索123,然后开始比较以找到完全匹配。当然,这并不比仅使用10000个元素的数组好多了,但它只是为了演示。

当你不确切地知道你将拥有多少元素时,哈希表是非常有用的,但哈希函数上的冲突数量将少于你的元素总数。 (这使散列函数“hash(x)= 0”非常非常糟糕。)您的表中可能有空白点,但理想情况下,大多数都会有一些数据。

答案 9 :(得分:0)

还要考虑速度。如果您的键是一个字符串并且您的值存储在一个数组中,那么您的哈希可以访问“接近”常量时间内的任何元素。将其与搜索字符串及其值进行比较。

答案 10 :(得分:0)

使用散列来查找表中的项目的主要优点,而不是使用键值对的原始键(BTW,它通常也存储在表中,因为哈希是是不可逆的),是那个..

...它允许将[原始]键的整个命名空间映射到散列值的相对较小的命名空间,从而允许散列表为检索项提供O(1)性能。

当考虑到处理冲突的额外时间等时,这个O(1)性能有点受到侵蚀,但总的来说哈希表对于存储和检索项目来说非常快,而不是仅仅基于[original]键值,通常为O(log N),例如二叉树(尽管这种树在空间上更有效)