Ruby 哈希表';s的钥匙存在吗?
哈希表是一种可以将键映射到值的数据结构。给定一个键,哈希函数将计算并告诉我们存储该值的槽/桶的索引。如果多个关键点映射到同一个插槽,则可能会从此插槽启动一个链接列表。如果没有足够的插槽容纳值,它将执行调整大小操作以找到更大的空间Ruby 哈希表';s的钥匙存在吗?,ruby,algorithm,hash,Ruby,Algorithm,Hash,哈希表是一种可以将键映射到值的数据结构。给定一个键,哈希函数将计算并告诉我们存储该值的槽/桶的索引。如果多个关键点映射到同一个插槽,则可能会从此插槽启动一个链接列表。如果没有足够的插槽容纳值,它将执行调整大小操作以找到更大的空间 哈希表的第一级存储桶始终是数组吗 钥匙存放在哪里?或者,它不必在每次哈希函数获取密钥并计算位置时都存储密钥 在Ruby语言中,像{:name=>“Wix”,:age=>18}这样的散列对象是否算作散列表?如果有,我需要问题2的答案 ruby名称散列有点误导。对大多数开发
{:name=>“Wix”,:age=>18}
这样的散列对象是否算作散列表?如果有,我需要问题2的答案35%10=5
然后将数据35=“some data”存储在该索引处,例如作为元组[35,“some data”]
然后我们得到更多的数据,25=“更多数据”和78=“很酷的东西”。同样,我们散列键,得到5
和8
。存储第二个很容易,我们只需将[78,“酷东西”]存储在数组中的第8位
但是存储[25,“更多数据”]是一个问题,因为在位置5
已经有一个存储桶。正如您已经指出的,这可以通过存储链接列表来解决。所以我们回到开头,而是存储[35,“一些数据”,nil]作为第一个值
要插入25
,我们只需更改它,使第一个元素指向第二个元素,然后得到array[5]=[35,“一些数据”,“更多数据”,nil]
访问 过了一会儿,用户想知道与“25”关联的值是多少 因为我们实现了一个hashmap,所以我们可以对值进行散列,
25%10=5
,并知道我们的对存储在位置5
。然后,我们只需迭代一个包含2个元素的链表,查找值[25]
,当我们找到它时,只需获取第二个值并将其返回给用户
实际上 当然,上面的例子过于简单,但它展示了哈希映射如何操作的基本思想 在现实世界中,散列算法当然比模除更复杂,但思想是一样的。密钥的散列总是转换为数组中的索引。一个好的散列算法应该是1。快速和2。随机的,以避免有很多空桶和有很多元素的几个桶 此外,我们的阵列不会有固定的长度10,但要聪明一点,尽量通过不太大来节省内存,但同时要有足够的内存,以避免不必要的不断收缩/增长,并使存储桶保持合理的短 在最好的情况下,您可以拥有数千个元素的映射,要访问其中一个元素,您只需对其进行散列,这需要相同的时间,与散列的大小无关,而无需迭代所有数千个元素并将每个元素与您要查找的元素进行比较
关于你的第三个问题,答案是肯定的 至于第二个,键存储在bucket中,但可能与它们的散列值一样 我不确定ruby如何在内部存储bucket,但通常它们可以通过多种方式实现,如数组、结构等。ruby名称哈希有点误导。对大多数开发人员来说,它们实际上是映射,这意味着您给了它们一个值,它们也给了您另一个相关的值。它们是hashmaps这一事实实际上只是一个实现细节,它使它们变得快速,事实上也是HashSet的相同原理,给定一个值,它只告诉您该值是否在该集中 为了简化一下,想象一下: 储存 您有一个包含10个元素的数组。您被告知要记住35=“一些数据”。然后散列索引(35),我将简化为将其除以数组长度的模,因此结果是
35%10=5
然后将数据35=“some data”存储在该索引处,例如作为元组[35,“some data”]
然后我们得到更多的数据,25=“更多数据”和78=“很酷的东西”。同样,我们散列键,得到5
和8
。存储第二个很容易,我们只需将[78,“酷东西”]存储在数组中的第8位
但是存储[25,“更多数据”]是一个问题,因为在位置5
已经有一个存储桶。正如您已经指出的,这可以通过存储链接列表来解决。所以我们回到开头,而是存储[35,“一些数据”,nil]作为第一个值
要插入25
,我们只需更改它,使第一个元素指向第二个元素,然后得到array[5]=[35,“一些数据”,“更多数据”,nil]
访问 过了一会儿,用户想知道与“25”关联的值是多少 因为我们实现了一个hashmap,所以我们可以对值进行散列,
25%10=5
,并知道我们的对存储在位置5
。然后,我们只需迭代一个包含2个元素的链表,查找值[25]
,当我们找到它时,只需获取第二个值并将其返回给用户
实际上 当然,以上是一个过于简单的例子,b