简单理解散列表

我们知道,散列表查询的时间复杂度为O(1),比起无序数组的O(n)和有序数组的O(logn)速度要快太多。在很多语言框架中已经帮我们封装好了散列表,比如java的Map、C#的Dictionary等。散列表也有其它叫法,比如字典、映射等。它主要是key-value结构,下面我们就看下散列表是怎么实现查询的O(1)。
散列表最主要的是对key进行散列运算,所以需要一个计算散列的函数。我们先制定一个规则,比如:
a=1
b=2
c=3
d=4
e=5
f=6
然后散列值等于每个字符的乘积之和。比如key=bad,则计算出的散列值就等于 2*1*4=8 。散列规则可以由你自由定义,但尽量保证能平均分布,减少出现相同散列值。
我们来看一个例子,假如存储下面这个javascript散列表:
var maps = {'bad':'evil','cab':'poll','dab':'jack'};
程序先为maps对象开辟内存空间,比如内存中连续的十个格子(内存地址),如下图:


先存入bad,对其进行散列运算: 2*1*4=8 ,然后我们将value值放到第八个格子里,如下图:


接着再存入cab,对其进行散列运算: 3*1*2=6 ,然后我们将value值放到第六个格子里,如下图:


最后存入dab,对其进行散列运算: 4*1*2=8 ,然后我们将value值放到第八个格子里。不过这时,第八个格子已经有值了,这里发生了散列值冲突。这时我们该怎么处理呢?可以将小格子里的值改为存放一个数组,即将两个键值对放入一个格子里,如下图:


以上我们就完成了一个散列表的存储,其中最主要就是对key进行散列计算。散列表可以实现查询、插入、删除的时间复杂度为O(1)。性能上要比无序数组(O(n))、有序数组(O(logn))等高出太多。

本文分享自微信公众号 - 一线码农聊技术(dotnetfly)。
如有侵权,请联系 [email protected] 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章