数据结构散列表

散列表用的是数组支持按照下标随机访问数据的特性,所以散列表其实就是数组的一种扩展,由数组演化而来。可以说,如果没有数组,就没有散列表。
简要的概括一下哈希表table hash_function(key){}

散列表

  • key 唯一标识,类比SQL表内主键
  • hash function是计算出value
  • 通过value找到table的对应值

散列函数

散列函数,顾名思义,它是一个函数。
我们可以把它定义成hash(key),其中 key 表示元素的键值,hash(key) 的值表示经过散列函数计算得到的散列值。

三点散列函数设计的基本要求:

  1. 散列函数计算得到的散列值是一个非负整数;
  2. 如果 key1 = key2,那 hash(key1) == hash(key2);
  3. 如果 key1 ≠ key2,那 hash(key1) ≠ hash(key2)。

所以完美的散列表其实是一个数组+key
即便像业界著名的MD5、SHA、CRC等哈希算法,也无法完全避免这种散列冲突。
而且,因为数组的存储空间有限,也会加大散列冲突的概率。

散列冲突

常用的散列冲突解决方法有两类

  • 开放寻址法(open addressing)
  • 链表法(chaining)

开放寻址法

  • 线性探测(Linear Probing)

    • 在散列表内存入数据时,如果遇到了散列值相同时候,向下遍历搜索空位,然后插入(电梯算法提高效率?)。
    • 寻值的时候就是将目标值和计算出来的散列值对应的值相同,否则遍历找到最后跳出。
  • 二次探测(Quadratic probing)

所谓二次探测,跟线性探测很像,线性探测的下标序列就是 hash(key)+0hash(key)+1hash(key)+2……而二次探测的下标序列就是 hash(key)+0hash(key)+1^2hash(key)+2^2……

  • 双重散列(Double hashing)

使用一组散列函数,如果第一个散列函数计算出来没有空位就用第二个散列函数,以此类推......

  • 用装载因子(load factor)来表示空位多少
    散列表的装载因子 = 填入表中的元素个数 / 散列表的长度
    • 所以这可以用来衡量是否需要扩容啊,快要满的时候就可以扩容了。

链表法

链表法是一种更加常用的散列冲突解决办法,相比开放寻址法,它要简单很多。在散列表中,每个“桶(bucket)”或者“槽(slot)”会对应一条链表,所有散列值相同的元素我们都放到相同槽位对应的链表中。

  • 我的理解
    • 其实就是扩容散列值对应的散列表的那行的解决办法
    • 用链表的方式可以存更多的数据在这行(散列值对应的)
    • 插入散列表的时候就要找到散列值对应的槽往链表的最后面插入
    • 查找和删除就只要找到散列值对应的槽然后遍历
  • 我的联想
    • 那么既然可以用链表那也可以用其他链式结构的数据结构
    • 那么可以用顺序结构吗?这样还能随机访问

设计散列函数

首先,散列函数的设计不能太复杂。过于复杂的散列函数,势必会消耗很多计算时间,也就间接的影响到散列表的性能。其次,散列函数生成的值要尽可能随机并且均匀分布,这样才能避免或者最小化散列冲突,而且即便出现冲突,散列到每个槽里的数据也会比较平均,不会出现某个槽内数据特别多的情况。
实际工作中,我们还需要综合考虑各种因素。这些因素有关键字的长度、特点、分布、还有散列表的大小等。散列函数各式各样,我举几个常用的、简单的散列函数的设计方法,让你有个直观的感受。
实际上,散列函数的设计方法还有很多,比如直接寻址法、平方取中法、折叠法、随机数法等,这些你只要了解就行了,不需要全都掌握。
(我感觉这些没有应用场景,过于苍白)

to be continued
2019年3月8日 20点28分


感谢您的阅读,请指正我的错误

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值