• 第三十四篇 玩转数据结构——哈希表(HashTable)


    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;
          }
      
      }
  • 相关阅读:
    阿里云容器服务多项重磅发布:高效智能、安全无界的新一代平台
    400倍加速, PolarDB HTAP实时数据分析技术解密
    先行一步,7大技术创新和突破,阿里云把 Serverless 领域的这些难题都给解了
    一图看懂云栖大会「云原生」重磅发布
    云栖发布|企业级互联网架构全新升级 ,助力数字创新
    3000份限量款云小宝手办全网首发,等你带回家!
    基于Delta lake、Hudi格式的湖仓一体方案
    git的clone和github的fork
    对vue的solt的理解
    对云信SDK的研究1
  • 原文地址:https://www.cnblogs.com/xuezou/p/9310556.html
Copyright © 2020-2023  润新知