使用glbindbuffers产生访问冲突_程序猿面试题-算法系列二、哈希表如何实现?地址冲突?...

哈希表经常会在面试中问道。这是因为它的确很重要。哈希表有很多应用,比如memcached的核心就是在内存中维护一张大的哈希表。

哈希表是如何实现的?如何解决地址冲突?

便于大家理解,我们倒着讲,先讲实现后讲概念。

哈希表有多种不同的实现方法,下面说的是由数组+链表组成的哈希表,也叫链地址法。

ac1fd6264effe445dd45c0f5c2fd97f8.png

哈希表

先说点简单易懂的。

首先分配一个指针数组,数组的每个元素是一个链表的头指针。

每个链表称为一个槽(Slot)。哪个数据应该放入哪个槽中由哈希函数决定,上图中我们简单地选取哈希函数h(x) = x % 11,这样任意数据 都可以映射成0~10之间的一个数,就是槽的编号,将数据放入某个槽的操作就是链表的插入操作。

如果每个槽里至多只有一个数据,这种情况下search、insert和delete操作的时间复杂度都是O(1)。

如果有多个数据放到同一个槽中,这称为碰撞(Collision),设计一个好的哈希函数可以把数据比较均匀地分布到各个槽中,尽量避免碰撞。

如果能把n个数据比较均匀地分布到m个槽中,每个糟里约有n/m个数据,则search、insert和delete和操作的时间复杂度都是O(n/m),如果n和m的比是常数,则时间复杂度仍然是O(1)。

一般来说,要处理的数据越多,构造哈希表时分配的槽也应该越多,所以n和m成正比这个假设是成立的。

不同数据结构 的时间复杂度:

e48fef329ecff0ec490d34ba2b7599cc.png

概念

哈希表(hash table)也叫散列表。

是根据关键码值(Key value)而直接进行访问的数据结构。

它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数(又叫哈希函数),比如上面例子的h(x) = x % 11,存放记录的数组叫做散列表。

哈希表的实现主要需要解决两个问题,哈希函数和冲突解决。

哈希函数 对不同的输出值得到一个固定长度的消息摘要。

哈希函数 当两个不同的输入值对应一个输出值时,就会产生“碰撞”,这个时候便需要解决冲突。

常见的冲突解决方法有开放定址法,链地址法,建立公共溢出区等。实际的哈希表实现中,使用最多的是链地址法。

链地址法的基本思想是,为每个 Hash 值建立一个单链表,当发生冲突时,将记录插入到链表中。 上面刚开始讲的就是这种方式。

e00982345c5e9f1bfd8f421f99be4494.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值