查看书籍Mining of Massive Datasets,第1.3.2节概述了哈希函数。没有计算机科学背景,这对我来说是一个新的东西; Ruby是我的第一语言,其中hash
似乎等同于Dictionary<object, object>
。我从未考虑过 这种数据结构的组合。
本书提到了哈希函数,作为实现这些字典数据结构的一种方法。本段:
首先,哈希函数h将哈希键值作为参数并生成 结果是一个桶号。桶号是一个整数,通常在 范围0到B - 1,其中B是桶的数量。哈希键可以是任何键 类型。哈希函数的直观属性是“随机化” 散列密钥
根据hash function
,具体到底是什么?听起来像桶是array-like
结构,而hash function
是某种算法/ array-like-structure
搜索,每次产生相同的桶号?这个隐喻桶里面有什么?
我一直都认为javascript对象/ ruby哈希/ etc不保证顺序。在实践中我发现键的顺序没有改变(实际上,我认为使用旧版本的Mozilla的Rhino解释器,JS对象命令DID改变了,但我不能确定......)。
这是否意味着这些hash functions
未解析哈希(Ruby)/对象(JS)?
单词hashing
是否具有不同的含义,具体取决于您使用计算机的级别?即看起来Ruby散列与C ++散列不一样......
答案 0 :(得分:5)
当您散列值时,任何有用的散列函数通常的范围小于域。这意味着在大量输入值(例如所有可能的字母组合)中,它将输出任何较小的值列表(以特定长度上限的数字)。这意味着多个输入值可以映射到相同的输出值。
在这种情况下,输出值被称为存储桶。
考虑函数 f(x)= x mod 2
这会产生以下输出;
1 => 1
2 => 0
3 => 1
4 => 0
在这种情况下,有两个桶(1和0),每个桶都有一堆输入值。
一个好的哈希函数将填充所有这些&#39;桶#39;同样地,所以启用更快的搜索等。如果你采用任何数字的mod,你可以查看存储桶,因此必须搜索比最初搜索时更少的结果,因为每个存储桶的结果都比整套投入。在理想情况下,哈希计算速度很快,每个桶中只有一个结果,这使得只有应用哈希函数才能进行查找。
这是一个简单的例子当然但希望你明白了吗?
答案 1 :(得分:2)
哈希函数的概念总是相同的。它是一个计算某个数字来表示对象的函数。这个数字的属性应该是:
让我们举一个非常人为的例子,说明我对此的意思以及为什么/如何使用哈希。
取所有自然数字。现在让我们假设检查两个数字是否相等是很昂贵的。
让我们定义一个相对便宜的哈希函数,如下所示:
hash = number % 10
这个想法很简单,只需将数字的最后一位数作为哈希值即可。在你得到的解释中,这意味着我们将所有以1结尾的数字放入一个假想的1桶中,所有数字在2桶中以2结尾等等......
这些存储桶并不真正作为数据结构存在。他们只是简单地推理哈希函数。
现在我们有了这个便宜的哈希函数,我们可以用它来降低其他东西的成本。例如,我们想要创建一个新的数据结构,以实现廉价的数字搜索。我们将这个数据结构称为哈希映射。
这里我们实际上将hash=1
的所有数字放在list / set / ...中,我们将带有hash=5
的数字放入他们自己的列表/集合等等。
如果我们想要查找某个数字,我们首先计算它的哈希值。然后我们检查对应于此哈希的列表/集合,然后仅比较“相似”数字以找到我们想要的确切数字。这意味着我们只需要进行廉价的哈希计算,然后必须通过昂贵的等式检查来检查1/10的数字。
请注意,我们使用哈希函数来定义新的数据结构。哈希本身不是数据结构。
答案 2 :(得分:0)
考虑一本电话簿。
想象一下,你想在电话簿中寻找唐老鸭。
必须查看每个页面以及该页面上的每个条目都是非常低效的。因此,我们不是这样做,而是做以下事情:
我们创建了一个索引
我们创建了一种从名称
对于电话簿,索引来自A-Z,而用于获取索引键的函数只是从Surname获得第一个字母。
在这种情况下,散列函数需要Donald Duck
并为您提供D
。
然后你拿D
并转到索引,其中以D开头的所有姓氏的人都是。
这将是一种非常简单的方式。
答案 3 :(得分:0)
让我用简单的语言解释一下。使用链接技术(开放散列或封闭寻址)处理冲突时,桶会进入画面
这里,每个数组条目应对应一个桶,每个数组条目(如果非空)将具有指向链表头部的指针。 (存储桶实现为链接列表)。
哈希表应使用哈希函数来计算桶数组的索引,从中可以找到所需的值。
也就是说,在检查元素是否在哈希表中时,首先对密钥进行哈希处理以找到要查看的正确桶。然后,遍历相应的链表以找到所需的元素。
同样,在添加或删除任何元素时,使用散列来查找相应的存储桶。然后,检查存储桶是否存在所需元素,并相应地通过遍历相应的链表将其添加到存储桶中。