什么是哈希表?

时间:2010-04-12 20:24:33

标签: hashtable

  • 它们是什么以及它们如何运作?
  • 他们在哪里使用?
  • 我应该何时(不)使用它们?

我一遍又一遍地听到这个词,但我不知道它的确切含义。

我听说他们允许关联数组通过散列函数发送数组键,将其转换为int然后使用常规数组。我是对的吗?

(注意:这不是我的功课;我去学校但他们只教我们信息学的基础知识)

3 个答案:

答案 0 :(得分:6)

Wikipedia似乎对它们的内容有一个非常好的答案。

当您想通过某个索引查找值时,应该使用它们。

至于什么时候你不应该使用它们...当你不想通过某个索引查找值时(例如,如果你想做的只是迭代它们。)

答案 1 :(得分:3)

你已经得到了它。它们是从任意事物(键)映射到任意事物(值)的非常的好方法。这个想法是你应用一个函数(一个哈希函数),它将键转换为索引到存储值的数组中;散列函数的速度通常是密钥大小的线性,当密钥大小远小于条目数(即典型情况)时,这是很好的。

棘手的一点是哈希函数通常是不完美的。 (存在完美的散列函数,但往往非常特定于特定的应用程序和特定的数据集;它们几乎不值得。)有两种方法可以解决这个问题,每种方法都需要存储具有值的密钥:one(开放式寻址) )是使用预定模式从数组中的位置向前看,其中 数组(所以你做一个线性查找,希望是一个简短的列表)。我读过源代码的生产代码的情况都是在加载因子过多的情况下使用链接动态重建哈希表。

答案 2 :(得分:1)

良好的哈希函数是允许您从任何给定输入创建分布式值的单向函数。因此,您将获得每个输入值的某些唯一值。它们也是可重复的,因此任何输入都将始终生成相同的输出。

好的哈希函数的一个例子是SHA1或SHA256。

假设您有一个用户数据库表。列为idlast_namefirst_nametelephone_numberaddress

虽然这些列中的任何一列都可能有重复,但我们假设没有行完全相同。

在这种情况下,id只是我们制作的唯一主键(代理键)。 id字段实际上不包含任何用户数据,因为我们找不到用户唯一的自然键,但是我们使用id字段来构建与其他表的外键关系。

我们可以从我们的数据库中查找这样的用户记录:

SELECT * FROM users
WHERE last_name = 'Adams'
AND first_name = 'Marcus'
AND address = '1234 Main St'
AND telephone_number = '555-1212';

我们必须搜索4个不同的列,使用4个不同的索引来查找我的记录。

但是,您可以创建一个新的“哈希”列,并存储所有四列组合的哈希值。

String myHash = myHashFunction("Marcus" + "Adams" + "1234 Main St" + "555-1212");

您可能会获得类似AE32ABC31234CAD984EA8的哈希值。

您将此哈希值存储为数据库中的列和索引。您现在只需要搜索一个索引。

SELECT * FROM users
WHERE hash_value = 'AE32ABC31234CAD984EA8';

一旦我们获得了所请求用户的id,我们就可以使用该值在其他表中查找相关数据。

这个想法是散列函数卸载了数据库服务器的工作。

不太可能发生碰撞。如果两个用户具有相同的哈希值,则很可能他们有重复的数据。