数据结构-散列(哈希)

本文详细介绍了哈希(散列)的概念,包括其在快速存取数据中的作用,以及如何通过散列函数将键映射到数组中的位置。文章还探讨了碰撞处理的两种常见方法:开链法和线性探测法。在开链法中,每个数组元素链接一个数据结构来存储多个键值对。线性探测法则在遇到碰撞时寻找下一个空位置存储数据。此外,文章提到了数组大小与数据存储效率的关系,以及何时选择开链法或线性探测法。
摘要由CSDN通过智能技术生成

散列(哈希)

散列也被称为哈希。散列后的数据可以快速存取。散列使用的数据结构是散列表。插入、删除和取用速度快,但是查找速度慢。
通过散列表存储数据时,通过散列函数将键映射为一个数字,数字的范围是0到散列表的长度。
当两个键映射为一个值的情况叫作碰撞。
散列表的数组长度应该是一个质数。

选择散列函数

散列函数的选择取决于键值的数据类型。除留余数法。如果键的类型是字符串将各个字符的ASCII的值的和除以数组的长度的余数。

hashTable.prototype.hashCode = function (str, size) {
    let hashCode = 0;
    // 霍纳算法计算hashCode
    for (let i = 0; i < str.length; i++) {
      hashCode = 37 * hashCode + str.charCodeAt(i);
    }
    index = hashCode % size;
    return index;
  }

碰撞处理

开链法

实现散列表的底层数组中,每个元素又是另一个数据结构。在创建存储散列过的键值的数组时,通过调用一个函数创建一个新的空数组,然后将该数组赋给散列表里的每个数组元素。这样就创建了一个二维数组

hashTable.prototype.put = function (key, value) {
    // 根据key获取索引位置
    // 根据索引取出bucket
    // 判断新增还是修改原来的值
    let index = this.hashCode(key, this.limit);
    let bucket = this.storage[index];
    if (bucket == null) {
      bucket = [];
      this.storage[index] = bucket;
    }
    for (let i = 0; i < bucket.length; i++) {
      let tuple = bucket[i];
      if (tuple[0] === key) {
        tuple[1] = value;
        return;
      }
    }
    bucket.push([key, value]);
    this.count++;
    if (this.count > this.limit * 0.75) {
      this.resize(this.getPrime(this.limit * 2));
    }
  }

线性检测法

线性探测法隶属于一种更一般化的散列技术:开放寻址散列。当遇到碰撞时,检测散列表的下一个的位置是否为空,如果为空则将数据存入该位置,如果不为空则继续检测下一个位置,直到找到一个空的位置为止。当存储数据的数组特别大时,使用线性检测法比开链法好。
如果数组的大小是待存储数据个数的1.5倍时,使用开链法;如果数组的大小是待存储数据个数的2倍及以上使用线性检测法。

 hashTable.prototype.lineDetectPut = function (key, value){
    let pos = this.hashCode(key);
    if(this.table[pos] === undefined){
      this.table[pos] = key;
      this.values[pos] = data;
    } else {
      while(this.table[pos] !== undefined){
        pos++;
      }
      this.table[pos] = key;
      this.values[pos] = value;
    }
  }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端御书房

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值