散列

散列表的基本思想是将关键字(key)通过散列函数映射到表中的一个位置,在查找的时候只要通过关键字就可以直接获取对应位置的值。那么主要的问题就是如何设计散列函数和如何在不同的关键字映射到同一位置的时候处理冲突。注意我们现在讨论的存放的仅仅是关键字,实际情况存放的是关键字+值。

处理冲突的方法

分离链表法

也称为拉链法,其基本思想是在冲突发生后使用链表来存储关键字散列值相同的值,查询的过程包括一次散列函数映射和链表的查询过程。

开放定址法

是不用链表处理冲突的散列表,其基本思想是当冲突发生后去找其他的空着的位置作为该关键字的位置。用公式来表示\(h_i(x)=(hash(x)+f(i)) mod TableSize\),f(i)为冲突解决函数。 不同的开放定址法如下:

  1. 线性探测法,即\(f(i)=i\)。也就是如果当前发生冲突,就查找下一个位置是否为空,如果为空,则放入,否则继续查找
  2. 平法探测法,即\(f(i)=i^2\)。
  3. 双散列,即\(f(i)=i*hash_2(x)\),也就是说用第二个散列函数作为处理冲突函数

##再散列
再散列是在散列表已经填的太满后,不论插入还是查找操作性能都大幅度降低,将原来散列表的所有值重新散列到一个更大的散列表的过程。

其他散列方法

布谷鸟散列

布谷鸟散列每个散列值对应两个盒子,它维护两个表,并且用两个独立的散列函数,布谷鸟散列保持不变的是一个项总是会被存储在两个位置之一。

跳房子散列

它尝试改进经典的线性探测算法,它的做法是给探测序列的最大长度加上一个上界,即令MAX_DIST为最大探测序列的上界,即项x必须在列出的hash(x),hash(x)+1,……,hash(x)+(MAX_DIST-1)的位置中找到,实现的方式使用一个信息,这在hash(x)后MAX_DIST个位置哪个被占了。

坚持原创技术分享,您的支持将鼓励我继续创作!