• Hash算法:双重散列


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

      此算法使用:

         (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 }
  • 相关阅读:
    CATransition
    OC中只有重写没有重载
    OC内存管理
    NSNotification
    关于一个小应用软件的思考
    tableView主从表在storyboard连线是 Selcetion Segue和Accessory Action的区别
    关于ios8模拟器不能输入中文问题以及软键盘不弹出问题
    UINavigation Bar中使用UIcollectionView,在UIcollectionView的顶端和低端出现空白的问题
    升级到Xcode6.2后 免证书真机调试出错的问题
    让UITableView 的 headerView跟随 cell一起滚动,tableHeaderView
  • 原文地址:https://www.cnblogs.com/magic-sea/p/12003883.html
Copyright © 2020-2023  润新知