seegongsik
我的单词本
数据

用名牌直接找到,哈希

假设你要在一大排储物柜里找朋友的东西。一个个门都打开,得花好久。可要是名字的头一个字母就定好了门号呢? 那只开那一扇门就行。看着值用计算定出格子,这个办法就是哈希。

01

名牌定下格子号

前面我们学过,值
按格子号一个个排着。
要找就得一个个格子地扫。
可要是看着值本身,
就能定出它的格子号呢?
就像用名字的字母定格子。
我们摆一个小计算,
喂进一个值,给出一个格子号。
这个计算叫哈希函数。

点一个值定出它的格子号
格子
0
1
2
3
4

点一个值。计算定出它的格子号,它就落进那个格子。

每个值都立刻有了格子。
不用纠结放哪儿。
计算把位置告诉你。
同一个值再放进来,
算出来还是同一个格子。
所以格子不会乱跑。
那么找的时候,
是不是也用同一个计算就行?

02

一算就直奔那个格子

找的时候,秘诀一样。
把要找的值喂进同一个计算,
得出格子号,
直接奔那个格子。
不用一个个格子地扫。
放进去用的计算
和找用的计算是一样的,
所以放的格子和找的格子正好对上。
所以一步就到。

要找的值
40
0
36
1
22
2
18
3
64
4
点一个要找的值

点一个要找的值。同一个计算给出格子号,不用扫,直接跳到那个格子。

没扫,一下就到了。
不管是一百个格子还是一万个,
费的功夫差不多。
算一次、跳一次,就完事。
这就是哈希快的原因。
不过有一件事让人在意。
两个不同的值,
要是算出来一样,会怎样?

03

两个奔向同一个格子

计算总是指出一个格子,
可值不同,格子不一定不同。
两个不同的值,
可能凑巧算出一样的结果。
那它俩就奔向同一个格子。
两个要挤进一个格子。
这样为同一个格子撞上,
叫做冲突。
冲突少见,但确实会发生。

0
1
2
3
4
依次点两个值

依次点两个值。它们算出来一样,都奔同一个格子,撞上了。

两个为同一个格子撞上了。
一个格子通常只放一个,
两个同时来就成了问题。
可也不能因此放弃哈希。
冲突偶尔才一次,
其余照样一步就快。
所以只在冲突时,
稍微单独处理一下就行。
来看看怎么处理?

04

冲突单独处理

解冲突主要有两条路。
一是把两个塞进一个格子。
格子里放个小包,
把撞上的值并排放进去。
二是挪到相邻的格子。
原来的格子满了,
就找个空着的相邻格子放进去。
不管哪种,都不丢值,
以后还能再找到。

0
1
17 322
3
4
选一种办法解开冲突

选一种处理办法点一下。塞进一个格子,或挪到相邻格子,把冲突解开。

冲突干净地解开了。
不管是塞一起还是挪到邻格,
值都安稳地落了位。
找的时候照同样的规矩,
撞过的值也能好好找到。
冲突偶尔有,处理又简单,
所以哈希照样又快又靠得住。
现在来把整件事理一理。

05

来理一理

归成一句话,是这样。
看着值,用计算定出格子号。
放的时候放那个格子,
找的时候同一个计算到那个格子。
所以不用扫,一步就到。
偶尔有别的值奔同一个格子,
冲突来了就单独处理。
塞一起,或挪到相邻格子。
用计算一下找到,这就是哈希。

依次点要点回顾一下

依次点要点回顾一下。(用计算定格子 → 用同一个计算一下找到 → 同格冲突 → 冲突单独处理)

现在你知道了用计算
一下找到值的聪明办法。
一个个扫格子的憋闷,
靠一次计算就痛快地解开了。
让放和找都变快的
这种本事,就是处理数据的力量。
下回又能用什么办法
把值存得更好、找得更好呢?
咱们接着一起看下去。

一句话总结哈希是看着值用计算定出格子号,然后直接往那个格子放、直接到那个格子找。它一步就到,不用一个个格子扫,所以很快。放进去和查找用的是同一个计算,所以放的格子和找的格子正好对上。也有短处。两个不同的值算出来一样,奔向同一个格子,就是冲突。那就在旁边处理,把它们一起塞进一个格子,或把一个挪到相邻的格子。一句话,哈希用计算定格子来一下找到,冲突就单独处理。
数据
如果有帮助,请支持我们