双重散列线性开型寻址散列开放寻址法)中的冲突解决技术。双重散列使用在发生冲突时将第二个散列函数应用于的想法。

  此算法使用:

     (hash1(key) + i * hash2(key)) % TABLE_SIZE 

  来进行双哈希处理。hash1()hash2() 是哈希函数,而 TABLE_SIZE 是哈希表的大小。当发生碰撞时,我们通过重复增加 步长i 来寻找键。

  第一个Hash函数:hash1(key) = key % TABLE_SIZE

1     /**
2 * 计算首次的Hash值
3 *
4 * @param key
5 * @return
6 */
7 private int hash1(int key) {
8 return (key % TABLE_SIZE);
9 }

  第二个Hash函数是:hash2(key) = PRIME – (key % PRIME),其中 PRIME 是小于 TABLE_SIZE 的质数

1     /**
2 * 发生碰撞是时继续计算Hash值
3 *
4 * @param key
5 * @return
6 */
7 private int hash2(int key) {
8 return (PRIME - (key % PRIME));
9 }

  第二个Hash函数表现好的特征:

  • 绝对不会产生 0 索引

  • 能在整个HashTable 循环探测

  • 计算会快点

  • 与第一个Hash函数互相独立

  • PRIME 与 TABLE_SIZE 是 “相对质数”

  

Java实现代码:

  1 package algorithm.hash;
2
3 /**
4 * 双重哈希
5 */
6 public class DoubleHash {
7 private static final int TABLE_SIZE = 13; // 哈希表大小
8 private static int PRIME = 7; // 散列函数值
9
10 private int[] hashTable;
11 private int curr_size; // 当前表中存的元素
12
13 public DoubleHash() {
14 this.hashTable = new int[TABLE_SIZE];
15 this.curr_size = 0;
16 for (int i = 0; i < TABLE_SIZE; i++)
17 hashTable[i] = -1;
18 }
19
20 private boolean isFull() {
21 return curr_size == TABLE_SIZE;
22 }
23
24 /**
25 * 计算首次的Hash值
26 *
27 * @param key
28 * @return
29 */
30 private int hash1(int key) {
31 return (key % TABLE_SIZE);
32 }
33
34 /**
35 * 发生碰撞是时继续计算Hash值
36 *
37 * @param key
38 * @return
39 */
40 private int hash2(int key) {
41 return (PRIME - (key % PRIME));
42 }
43
44 /**
45 * 向Hash表中存值
46 *
47 * @param key
48 */
49 private void insertHash(int key) {
50 /* 表是否已满 */
51 if (isFull()) {
52 return;
53 }
54
55 /* 获取首次的Hash值 */
56 int index = hash1(key);
57
58 // 如果发生碰撞
59 if (hashTable[index] != -1) {
60 /* 计算第二次的Hash值 */
61 int index2 = hash2(key);
62 int i = 1;
63 while (true) {
64 /* 再次合成新的地址 */
65 int newIndex = (index + i * index2) % TABLE_SIZE;
66
67 // 如果再次寻找时没有发生碰撞,把key存入表中的对应位置
68 if (hashTable[newIndex] == -1) {
69 hashTable[newIndex] = key;
70 break;
71 }
72 i++;
73 }
74 } else {
75 // 一开始没有发生碰撞
76 hashTable[index] = key;
77 }
78 curr_size++; // Hash表中当前所存元素数量加1
79 }
80
81 /**
82 * 打印Hash表
83 */
84 private void displayHash() {
85 for (int i = 0; i < TABLE_SIZE; i++) {
86 if (hashTable[i] != -1)
87 System.out.println(i + " --> " + hashTable[i]);
88 else
89 System.out.println(i);
90 }
91 }
92
93 public static void main(String[] args) {
94 int[] a = {19, 27, 36, 10, 64};
95
96 DoubleHash doubleHash = new DoubleHash();
97 for (int i = 0; i < a.length; i++)
98 doubleHash.insertHash(a[i]);
99
100 doubleHash.displayHash();
101 }
102
103 }

最新文章

  1. html5页面结构
  2. unslider.js 实现移动web轮播
  3. [Leetcode][JAVA] Interleaving String
  4. objective-c可变字典
  5. unity3d 游戏插件 溶解特效插件 - Dissolve Shader
  6. PHP+jQuery 注册模块的改进之三:使用 Smarty3
  7. BFS寻路算法的实现
  8. web开发常用图片格式
  9. ubuntu10.04版本下android源码的编译
  10. nginx 重写 rewrite 基础及实例(转)
  11. /bin/sh^M: bad interpreter:解决办法
  12. java.lang.NoClassDefFoundError: com/mchange/v2/ser/Indirector
  13. Python中模块之logging &amp; subprocess的讲解
  14. Docker基础知识介绍
  15. CF1038E Maximum Matching 搜索/区间DP
  16. git 查看提交的信息diff
  17. centos安装redis并设置开机启动
  18. orcle查询记录的每天的第一条
  19. shell-008:检测502
  20. Elasticsearch-PHP 索引操作2

热门文章

  1. Spring5(五)——AOP
  2. Docker修改容器中的时间
  3. js不记录某个url链接历史访问,返回时不返回该链接
  4. mysql中varchar类型和datetime类型字段进行比较
  5. node 在centos 6.5 上 安装过程中出现/usr/lib64/libstdc++.so.6: version &#39;GLIBCXX_3.4.19&#39; not found问题的解决
  6. Wannafly挑战赛10F-小H和遗迹【Trie,树状数组】
  7. UOJ#454-[UER #8]打雪仗【通信题】
  8. 从0到1告诉你搭建完整Python+requests接口自动化测试框架!
  9. Radius协议-学习
  10. 使用python -m pip install 和 pip install 安装包有什么区别?