cuckoo hash(布谷鸟散列)
这里不多对cuckoo hash(布谷鸟散列)多做介绍,简单带过它的优势:
cuckoo hash主要针对hash 冲突的时候,提出的一个高效的解决方案,它主要特点是查找次数有保障,空间利用率高,适用数据量大而读多写少的场景:
通过两组或多组Hash散列,一次性计算两个(或多个)Hash位置,保证了每个元素最坏的查找次数。
时间效率上:cuckoo hash冲突做多需要寻找2次,有最坏的查找性能保障;
空间效率上:无需要链式的额外的链表结构,可以直接利用置换hash位置,所以空间利用率高;
适用场景上:适合读多写少的场景,写的时候需要不断置换(冲突时)或重新hash,比常规散列消耗多一些;
cuckoo hash适用于快速查找操作的应用开发有:如网关路由、NAT表维护、防火墙规则匹配、实时数据处理、数据包收取等,这是都是得益于cuckoo hash有几乎恒定的查找时间。
BFS(广度优先搜索)
BFS(广度优先搜索)的核心概念可以用三句话概括:
- 搜索方式:从起点开始,像水波纹一样向外扩散,先访问距离近的,再访问距离远的
- 数据结构:使用队列(FIFO)存储待访问的节点,保证按层次顺序访问
- 特性保证:由于是按层次访问,首次到达目标点的路径一定是最短路径
示意图:
1
/ \ 层次遍历顺序:
2 3 1 -> [2,3] -> [4,5,6,7]
/ \ / \
4 5 6 7
这就是BFS最基本的概念:按层次扩展的搜索策略。
为何在cuckoo hash中得以适用
cuckoo hash在插入数据时候,发现插入目标位置已满,这时候是需要检索并且移动路径的,即发生布谷鸟的剔除效应,该剔除思想即是cuckoo hash的核心设计了!
布谷鸟剔除效应指的是:
通过占用目标数据的hash位置,这时候被占用的源数据会以同样的方式去占用它的第二目标位置,以此类推,直到找到一个空巢穴为止,整条路径完成移动,数据完成插入。
BFS正是在布谷鸟剔除效用的路径寻找上,被cuckoo hash选中!来看看为何被选中,那就做个对比看个例子喽:
假设有这样的哈希表:
桶0:[A, B] // 需要在这里插入新键X
桶1:[C, D]
桶2:[E, 空] // 这里有一个空槽
桶3:[F, G]
BFS 搜索过程:
第一次探索:检查桶0中元素可以移动的位置
从桶0[A]开始,假如通过计算:
A可以移动到桶2或桶3
B可以移动到桶1或桶3
此刻的队列状态:[桶2(A), 桶3(A), 桶1(B), 桶3(B)]
检查状态队列第一个位置(桶2)
发现桶2有空槽!
找到移动路径:A -> 桶2[空]
DFS 搜索过程:
第一次探索:
桶0[A] -> 桶3[F] -> 桶1[C] -> 桶2[E](达到最大深度,回溯)
回溯并尝试新路径:
桶0[A] -> 桶3[F] -> 桶1[D](无可用位置,继续回溯)
继续回溯和探索:
桶0[A] -> 桶3[G](无可用位置,继续回溯)
尝试从A的另一个可能位置:
桶0[A] -> 桶2[空] // 找到空槽!
BFS妥妥的完胜!!BFS找到最短移动路径只需1步,不需要检查其他可能路径,因为它们至少需要2步或更多,这就是BFS的特点。
再回过头看来
广度优先算法有两个好处:
- bfs是层次查找的,能够高效地找到最短的移动链
- 避免了深度优先搜索按深度查找,可能导致的过长移动链
这就是为什么cuckoo hash选择 BFS 能高效地找到最优解路径的原因了!
以最简单的例子,了解最巧妙的思想,精炼再精炼!