其实很简单:
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 、怎么在冲突的时候还能知道是不是我要找的元素;
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.