闲来无事 想到的哈希冲突 解决方案 思路

2020-06-11 12:15:20 +08:00
 guagual

其实很简单:

1 、大前提是选择哈希结果平均分布的哈希函数,这个有很多种方案,不是关键;

2 、在存储哈希结果的时候,

2.1 、如果当前地址没有被占用,则直接存放值;

2.2 、如果当前地址已经被占用了:

2.2.1 、如果当前地址存放的是一个值:则在该地址存放指针,该指针指向一个链表,同时需要将原来这个位置的值放入链表,新的值也加入链表;

2.2.2 、如果当前地址存放的是一个指针:直接在这个指针所指的链表里面加入新的值节点即可;

ps:上面所说的值 是一个 结构体对象,这个结构体对象里面即有 key 又有 hash(key)和 value,以下简称值;

3 、这样的话:当查找的时候通过将 key 传入 hash 函数的时候,得到哈希之后的 hashkey:

3.1 、如果 hashkey 这个地址里面存储的是一个值,那么说明这个位置没有哈希冲突,直接取出值返回即可;

3.2 、如果 hashkey 这个地址里面存储的是一个指针,那么说明这个 key 有哈希冲突,所以就按照有哈希冲突的方法来处理:

3.2.1 、先找到这个指针对应的链表,然后挨个遍历链表,查看每一个元素,查看该元素的 key 是否和我所传入的 key 相同:

3.2.1.1 、如果相同则说明是我要找的那个值,查找成功;

3.2.1.2 、如果不同则继续往后找,直到找到链表最后都没有我当前的 key 的话,则整个查找失败。

总结:

1 、哈希冲突不可避免;

2 、怎么在冲突的时候还能知道是不是我要找的元素;

3527 次点击
所在节点    程序员
29 条回复
guagual
2020-06-11 23:40:33 +08:00
@pakro888 谢谢建议
guagual
2020-06-11 23:41:03 +08:00
@lance6716 看来我很危险了,一定要多看书
guagual
2020-06-11 23:42:01 +08:00
@redford42 👍,厉害厉害。红黑树可以降低复杂度,据说是链表超过 8 个 node 再转换成红黑树。
guagual
2020-06-11 23:42:16 +08:00
@xsqfjys 谢谢宝贵的建议
guagual
2020-06-11 23:42:36 +08:00
@nightwitch 在大佬面前献丑了。
guagual
2020-06-11 23:43:24 +08:00
@yuudachiPoi 区别只是冲突之后的存储方式不一样吧?
Jacky23333
2020-06-12 00:49:02 +08:00
这不就是老师课堂上讲的拉链法吗....不过楼主如果是自己独立思考出来的那还是挺厉害的,点赞!
larisboy
2020-06-12 12:08:07 +08:00
这种算法在极端情况下复杂度会变成 O ( n )把,感觉并不完美
guagual
2020-06-12 12:12:16 +08:00
@larisboy 所以有大佬进行了改进,如果链表长度大于 8,则将链表存储改为红黑树存储。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/680623

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX