1.. 整型哈希函数的设计
  • 小范围正整数直接使用
  • 小范围负整数整体进行偏移
  • 大整数,通常做法是"模一个素数"
 
2.. 浮点型哈希函数的设计
  • 转成整型进行处理
 
3.. 字符串哈希函数的设计
  • 转成整型进行处理
  • 简单变形优化
  • 防止整型溢出优化
  • 具体代码实现
4.. 复合类型哈希函数的设计
  • 转成整型进行处理

5.. 哈希函数的设计原则

6.. 哈希冲突的处理
  • 链地址法
  • 开放地址法之线性探测
  • 开放地址法之平方探测

  • 开放地址法之二次哈希

7.. 哈希表的动态空间处理

8.. 实现哈希表的业务逻辑

  • import java.util.TreeMap;
    
    public class HashTable<K, V> {
    
        private final int[] capacity
    = {53, 97, 193, 389, 769, 1543, 3079, 6151, 12289, 24593,
    49157, 98317, 196613, 393241, 786433, 1572869, 3145739, 6291469, 12582917,
    25165843, 50331653, 100663319, 201326611, 402653189, 805306457, 1610612741};
    private static final int upperTol = 10;
    private static final int lowerTol = 2;
    private int capacityIndex = 0;
    private TreeMap<K, V>[] hashTable;
    private int M;
    private int size; public HashTable() { this.M = capacity[capacityIndex];
    this.size = 0;
    hashTable = new TreeMap[M];
    for (int i = 0; i < M; i++) {
    hashTable[i] = new TreeMap<>();
    }
    } private int hash(K key) {
    return key.hashCode() & 0x7fffffff % M;
    } public void add(K key, V value) { TreeMap<K, V> map = hashTable[hash(key)]; if (map.containsKey(key)) {
    map.put(key, value);
    } else {
    map.put(key, value);
    size++;
    if (size >= upperTol * M && capacityIndex + 1 < capacity.length) {
    capacityIndex++;
    resize(capacity[capacityIndex]);
    }
    }
    } public V remove(K key) { TreeMap<K, V> map = hashTable[hash(key)]; V ret = null;
    if (map.containsKey(key)) {
    ret = map.remove(key);
    size--;
    if (size < lowerTol * M && capacityIndex - 1 >= 0) {
    capacityIndex--;
    resize(capacity[capacityIndex]);
    }
    }
    return ret;
    } public void set(K key, V value) { TreeMap<K, V> map = hashTable[hash(key)]; if (!map.containsKey(key)) {
    throw new IllegalArgumentException(key + "doesn't exist.");
    } else {
    map.put(key, value);
    }
    } public boolean contains(K key) { return hashTable[hash(key)].containsKey(key);
    } public V get(K key) { return hashTable[hash(key)].get(key);
    } private void resize(int newM) { TreeMap<K, V>[] newHashTable = new TreeMap[newM];
    for (int i = 0; i < newM; i++) {
    newHashTable[i] = new TreeMap<>();
    } int oldM = M;
    M = newM;
    for (int i = 0; i < oldM; i++) {
    TreeMap<K, V> map = hashTable[i];
    for (K key : map.keySet()) {
    newHashTable[hash(key)].put(key, map.get(key));
    }
    } this.hashTable = newHashTable;
    } }

第三十四篇 玩转数据结构——哈希表(HashTable)的更多相关文章

  1. 第二十四篇 玩转数据结构——队列(Queue)

          1.. 队列基础 队列也是一种线性结构: 相比数组,队列所对应的操作数是队列的子集: 队列只允许从一端(队尾)添加元素,从另一端(队首)取出元素: 队列的形象化描述如下图: 队列是一种先进 ...

  2. 第三十二篇 玩转数据结构——AVL树(AVL Tree)

          1.. 平衡二叉树 平衡二叉树要求,对于任意一个节点,左子树和右子树的高度差不能超过1. 平衡二叉树的高度和节点数量之间的关系也是O(logn) 为二叉树标注节点高度并计算平衡因子 AVL ...

  3. 第二十六篇 玩转数据结构——二分搜索树(Binary Search Tree)

          1.. 二叉树 跟链表一样,二叉树也是一种动态数据结构,即,不需要在创建时指定大小. 跟链表不同的是,二叉树中的每个节点,除了要存放元素e,它还有两个指向其它节点的引用,分别用Node l ...

  4. C++第三十四篇 -- 安装Windows Driver后,编译以前项目出现打不开lib文件

    VS2017默认是没有安装WDK的,但是我们写驱动文件的话需要用到WDK.不过安装了WDK后,发现以前一些正常的项目在Release模式下编译会报LINK1104,无法打开.lib的错误 针对这个错误 ...

  5. Android UI开发第三十四篇——SlidingPaneLayout

    SlidingPaneLayout也是系统支持的高级控件,是Android团对在2013 google IO大会期间更新的Support库(Version 13)中新加入的重要的功能.它支持左右滑动菜 ...

  6. 第三十四篇 Python面向对象之 反射(自省)

    什么是反射? 反射的概念是由Smith在1982年提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省).这一概念的提出很快引发了计算机科学领域关于应用反射性的研究.它首先被程序语 ...

  7. 第二十八篇 玩转数据结构——堆(Heap)和有优先队列(Priority Queue)

          1.. 优先队列(Priority Queue) 优先队列与普通队列的区别:普通队列遵循先进先出的原则:优先队列的出队顺序与入队顺序无关,与优先级相关. 优先队列可以使用队列的接口,只是在 ...

  8. 第二十五篇 玩转数据结构——链表(Linked List)

          1.. 链表的重要性 我们之前实现的动态数组.栈.队列,底层都是依托静态数组,靠resize来解决固定容量的问题,而"链表"则是一种真正的动态数据结构,不需要处理固定容 ...

  9. 第三十四篇:在SOUI中使用异步通知

    概述 异步通知是客户端开发中常见的需求,比如在一个网络处理线程中要通知UI线程更新等等. 通常在Windows编程中,为了方便,我们一般会向UI线程的窗口句柄Post/Send一个窗口消息从而达到将非 ...

随机推荐

  1. Python 文件&异常 初学者笔记

    文件 读取整个文件 with open('pi_30_digits.txt') as file_object :#Python在当前执行文件目录寻找指定文件#filename = 文件的绝对路径或相对 ...

  2. C++->10.3.6.设有两个按升序排列的二进制文件a和b,将他们合并成一个新的升序二进制数据文件file。

    #include<iostream.h> #include<stdlib.h> #include<string.h> #include<fstream.h&g ...

  3. JS:获取标签的6个方法+获取html+获取body

    JS 获取标签的方法 通过class: document.getElementsByClassName('class名');返回数组通过name: document.getElementsByName ...

  4. AGC001 E - BBQ Hard [组合数]

    这题就是要求 \(\sum_{i=1}^{n} \sum_{j=i+1}^{n} C(a_i+a_j+b_i+b_j,a_i+a_j)\) 考虑搞一搞,\(C(a_i+a_j+b_i+b_j,a_i+ ...

  5. mac 非安全模式 开启

    https://github.com/callmelaoda/communicate/issues/8 open -a Google\ Chrome --args --disable-web-secu ...

  6. c基本语法和数据类型

    一.C语言结构 C 程序主要包括以下部分: 预处理器指令 函数 变量 语句 & 表达式 注释 二.基本语法 1.  分号是语句结束符. 2. 单行注释//.多行注释/* */. 3. 标识符是 ...

  7. gulp常用插件之gulp-useref使用

    更多gulp常用插件使用请访问:gulp常用插件汇总 gulp-useref这是一款可以将HTML引用的多个CSS和JS合并起来,减小依赖的文件个数,从而减少浏览器发起的请求次数.gulp-usere ...

  8. TCP常用拆包处理

    1.演示环境为windows 10 1903 2.演示代码 #include "pch.h" #include <iostream> #include <WinS ...

  9. C 库函数 - sprintf()

    C 库函数 - sprintf() C 标准库 - <stdio.h> 描述 C 库函数 int sprintf(char *str, const char *format, ...) 发 ...

  10. C 库函数 - modf()

    C 库函数 - modf() C 标准库 - <math.h> 描述 C 库函数 double modf(double x, double *integer) 返回值为小数部分(小数点后的 ...