我的编程空间,编程开发者的网络收藏夹
学习永远不晚

JavaScript 数据结构之散列表的创建(2)

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

JavaScript 数据结构之散列表的创建(2)

前言:

上一篇我们介绍了什么是散列表,并且用通俗的语言解析了散列表的存储结构,最后动手实现了一个散列表,相信大家对散列表已经不陌生了。

如果还不清楚散列表,请先阅读上一篇文章:JavaScript 数据结构之散列表的创建(1)

上篇末尾我们遗留了一个问题,就是将字符串转化为散列值后可能出现重复。当以散列值(hash 值)为 key 存储数据时,就会有覆盖已有数据的风险。本篇我们看如何处理散列值冲突的问题,并实现更完美的散列表。

一、处理散列值冲突

有时候一些键会有相同的散列值。比如 aab 和 baa,从字符串的角度来说它们是不同的值,但是按照我们的散列函数逻辑,将每个字母的 Unicode 码累加得出的散列值,一定是一样的。

我们知道在 JavaScript 对象当中,如果赋值时指定的 key 已存在,那么就会覆盖原有的值,

比如这个例子:

var json = { 18: '雷欧' }
json[18] = '欧布'
console.log(json) // { 18: '欧布' }

为了避免上述代码中出现的风险,我们需要想办法处理,如何使 key != key,则 hash != hash

目前可靠的方法有两个,分别是:分离链接 和 线性探查

1.分离链接

分离链接法是指在散列表存储数据时,value 部分用 链表 来代替之前的 键值对。键值对只能存储一个,而链表可以存储多个键值对。如果遇到相同的散列值,则在已有的链表中添加一个键值对即可。

我们需要重写三个方法:put、get 和 remove。我们看如何实现:

class HashTableSeparateChaining {
  constructor() {
    this.table = {}
  }
}

2.put 方法

首先还是基本的类结构,然后看 put 方法:

put(key, value) {
  if(key !== null && value !== null) {
    let pos = this.hashCode(key)
    if(!this.table[pos]) {
      this.table[pos] = new LinkedList()
    }
    this.table[pos].push(new ValuePair(key, value))
    return true;
  }
  return false;
}

LinkedList 类是标准的链表类,在链表篇讲过如何实现,这里直接使用

对比上篇的散列表 put 方法,你会发现差别不大,变化的部分如下:

// 变化前
this.table[pos] = new ValuePair(key, value)
// 变化后
if(!this.table[pos]) {
  this.table[pos] = new LinkedList()
}
this.table[pos].push(new ValuePair(key, value))

优化后的逻辑是,在存储数据时,将键值对存在一个链表里。如果有相同的 hash 值,则向已有的链表中添加一个键值对,这样就避免了覆盖。

不过这种方式也有弊端,每添加一个键值对就要创建一个链表,会增加额外的内存空间。

3.get 方法

get 方法:

get(key) { 
  let linkedList = this.table[this.hashCode(key)]
  if(linkedList && !linkedList.isEmpty()) {
    let current = linkedList.getItemAt(0);
    while(current) {
      if(current.value.key == key) {
        return current.value.value
      }
      current = current.next
    }
  }
  return undefined; 
}

新的 get 方法明显比之前的复杂了许多。主要逻辑是根据 key 找到一个链表,然后再遍历链表找到与参数 key 相匹配的键值对,最后返回找到的值。

while 循环中使用 return 可以直接中止当前函数

到此这篇关于 JavaScript 数据结构之散列表的创建的文章就介绍到这了,更多相关 JavaScript 散列表内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

JavaScript 数据结构之散列表的创建(2)

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

JavaScript数据结构之散列表怎么创建

本文小编为大家详细介绍“JavaScript数据结构之散列表怎么创建”,内容详细,步骤清晰,细节处理妥当,希望这篇“JavaScript数据结构之散列表怎么创建”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。一、处
2023-06-30

Python学习之day3数据结构之列表

数据结构之列表一、列表定义      列表是处理一组有序项目的数据结构,即你可以在一个列表中存储一个序列的项目。列表中的项目应包括在方括号中,这样python就是知道你是指名了一个列表。一旦你创建了一个列表,你可以添加、删除或者搜索列表中的
2023-01-31

power Designer 导入 excel 表结构数据 创建表

二、打开PowerDesigner,创建物理模型(Physical Data Model)三、在PowerDesigner菜单栏中,依次点击“Tools ->Excute Commands->Edit/Run Script..四、修改如下脚本,指定excel所
power Designer 导入 excel 表结构数据 创建表
2015-03-16

详解redis数据结构之压缩列表

详解redis数据结构之压缩列表 redis使用压缩列表作为列表键和哈希键的底层实现之一。当一个列表键只包含少量的列表项,并且每个列表项都是由小整数值或者是短字符串组成,那么redis就会使用压缩列表存储列表项;同理,当一个哈希表包含的键值
2022-06-04

PHP数据结构:散列表的实现原理,探究数据快速查找的奥秘

散列表是一种高效的数据结构,它通过将数据映射到固定大小的数组(“桶”)实现快速查找,每个桶包含具有相同键的数据。php 中的散列表使用哈希函数,将任意大小的数据转换为固定长度的整数,该整数用于计算数据在散列表中的桶。PHP 数据结构:散列表
PHP数据结构:散列表的实现原理,探究数据快速查找的奥秘
2024-05-15

JavaScript数据结构yoctoqueue队列链表代码分析

这篇文章主要为大家介绍了JavaScript数据结构yoctoqueue队列链表代码分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2022-12-19

Javascript数据结构之栈和队列怎么实现

本篇内容主要讲解“Javascript数据结构之栈和队列怎么实现”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Javascript数据结构之栈和队列怎么实现”吧!栈(stack)栈是一种具有 「
2023-06-30

数据库的结构、创建、使用

从逻辑上看:描述信息的数据存在数据库中并由DBMS统一管理从物理上看:描述信息的数据事宜文件的方式存储在物理磁盘上数据库文件分为:1.数据文件:存放数据库数据和数据仓库对象的文件主要数据文件(.mdf)+次要数据文件(.ndf)主要数据文件只能有一个,存放数据
数据库的结构、创建、使用
2015-08-09

Java数据结构之链表的概念及结构

这篇文章主要介绍了数据链表的概念及结构,链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。想进一步了解的同学,可以参考阅读本文
2023-05-14

编程热搜

目录