JavaScript(ES6)数据结构与算法之哈希表

5. 哈希表(散列表/字典)

文章目录

    • 5. 哈希表(散列表/字典)
      • 5.1 概念
      • 5.2 哈希表的实现
      • 5.3 扩容

5.1 概念

  • 基于数组实现,存放键值对:结构是数组,对输入的键进行变换(哈希函数)得到HashCode
  • 解决冲突(不同下标值HashCode相同)
    • 链地址法(常用):每个数组单元存储数组或链表,出现相同映射就链式延伸添加
    • 开放地址法(少):寻找空白单元格(线性探测、二次探测、再哈希法)来添加重复的数据,可能会扩容
  • 优势:
    • 非常快速的插入删除查找操作
    • 速度比树快,编码比树容易
  • 劣势:
    • 数据没有顺序,不能按大小等遍历
    • key不允许重复
  • 装填因子:
    • 装填因子=总数据项/哈希表长度
    • 装填因子越大,探测长度越长,哈希表插入和搜索效率降低,链地址法随装填因子改变,效率改变更小,因此更常被采用
    • 链地址法装填因子可以大于1,开放地址法装填因子最大为1
  • 设计哈希函数
    • 快速计算,多项式的优化:霍纳法则(秦九韶算法),降低时间复杂度从O(N^2)到O(N)
    • 均匀分布:使用常量的地方,尽量使用质数

5.2 哈希表的实现

  • 常见方法:

    • 存放元素
    • 获取元素
    • 删除元素
    • 哈希表扩容
  • 封装

    export class HashTable{constructor(){this.storage=[]//数组存储元素this.count=0;//当前存放了多少个元素this.limit=8;//容量}//哈希函数hashFunc(str,max){//1.定义hashCodelet hashCode = 0;//2.霍纳算法for(let i=0;i<str.length;i++){hashCode = 31*hashCode + str.charCodeAt(i);}hashCode = hashCode%max;return hashCode;}//存放元素方法put(key,value){//1.根据key映射到indexconst index = this.hashFunc(key,this.limit);//2.取出数组//storage的每个index都可以有一个bucketlet bucket = this.storage[index];if(bucket === undefined){bucket = [];this.storage[index] = bucket;}//3.判断是插入还是修改操作let overwride = false;for(let i = 0;i<bucket.length;i++){let tuple = bucket[i];//bucket是二维数组,一个放key,一个放valueif(tuple[0] === key){tuple[1]=value;overwride = true;}}//4.如果没有覆盖(没有该key),则新增if(!overwride){bucket.push([key,value]);this.count++;}}//获取元素方法get(key){//1.根据key获得Indexconst index = this.hashFunc(key,this.limit);//2.获得bucketconst bucket = this.storage[index];if(bucket === undefined){return null;}//3.遍历bucket,一个个查找for(let i = 0;i<bucket.length;i++){let tuple = bucket[i];if(tuple[0] === key){return tuple[1];}}//4.遍历完,没有找到则返回nullreturn null}//删除元素方法remove(key){//1.根据key获得indexconst index = rhis.hashFunc(key,this.limit);//2.获得bucketconst bucket = this.storage[index];if(bucket === undefined){return null;}//3.遍历bucket,找到元素,并将删除的元素返回for(let i=0;i<bucket.length;i++){let tuple = bucket[i];if(tuple[0] === key){bucket.splice(i,1);this.count--;return tuple[1]}}}isEmpty(){return this.count===0;}size(){return this.count;}}
    

5.3 扩容

装填因子过大会降低操作效率,这时可以考虑扩容,扩容后所有数据项都需要修改,因为扩容后哈希函数计算的index会改变

常见情况是loadFactor>0.75(如java)时进行扩容

  • 哈希表的扩容(也可能缩小容量)

    resize(newLimit){//1.保留原数组中的内容let oldStorage = this.storage;//2.重置属性this.limit = newLimit;this.storage = [];this.count = 0;//3.取出oldStorage所有的元素,重新放入到storageoldStorage.forEach((bucket)=>{if(bucket === null){return}for(let i = 0;i<bucket.length;i++){let tuple = bucket[i];//直接调用put方法,limit已经更新了this.put(tuple[0],tuple[1])}})}
    

    在put方法和remove方法中调用

    const MAX_LOAD_FACTOR = 0.75;
    const MIN_LOAD_FACTOR = 0.75;put(key,value){//略if(!overwride){bucket.push([key,value]);this.count++;if(this.count>this.limit*MAX_LOAD_FACTOR){this.resize(this.limit*2);}}}remove(key){//略for(let i = 0;i<bucket.length;i++){let tuple = bucket[i];if(tuple[0] === key){bucket.splice(i,1);this.count--;//设置容量不小于8if(this.limit>8&&this.count<this.limit*MIN_LOAD_FACTOR){this.resize(Math.floor(this.limit/2))}}return tuple[1];}
    }
    
  • 判断数字是否为质数(素数)

    容量最好是质数,大于1的自然数中,只能被1和自己整除的数

    //如果一个数可以被大于其平方根的整数整除,那么一定也可以被小于其平方根的整数整除
    //添加方法判断
    isPrime(num){//1.获取平方根,向上取整var temp = Math.ceil(Math.sqrt(num))for(let i=2;i<=temp;i++){if(num%i===0){return true;}    }return false;
    }
    
  • 扩容为质数

    //添加方法获得质数
    getPrime(num){while(!isPrime(num)){num++;}return num;
    }//修改put 
    let newLimit = this.getPrime(this.limit*2);
    this.resize(newLimit)
    //修改remove
    let newLimit = this.getPrime(Math.floor(this.limit/2));
    this.resize(newLimit)
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/577790.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JavaScript 数组【详解】

Hi i,m JinXiang ⭐ 前言 ⭐ 本篇文章主要介绍JavaScript中数组详解 数组声明/基础操作以及部分理论知识 &#x1f349;欢迎点赞 &#x1f44d; 收藏 ⭐留言评论 &#x1f4dd;私信必回哟&#x1f601; &#x1f349;博主收将持续更新学习记录获&#xff0c;友友们有任何问题可…

C/C++ BM2链表内指定区间反转

文章目录 前言题目1. 解决方案一1.1 思路阐述1.2 源码 2. 解决方案二2.1 思路阐述2.2 源码 总结 前言 这题是BM1的升级版&#xff0c;不过是把完整的链表翻转变成了指定区间。 题目 描述 将一个节点数为 size 链表 m 位置到 n 位置之间的区间反转&#xff0c;要求时间复杂度 …

Sqlserver数据库触发器sql案例

前言 需求&#xff1a;当主数据状态更新为无效时&#xff0c;同时将关系表中的关联记录修改成无效状态。 为什么要From inserted去查询主键和状态&#xff1f; 在 SQL Server 中&#xff0c;触发器使用 inserted 和 deleted 临时表来引用发生 INSERT、UPDATE 或 DELETE 操作…

手机蓝牙在物联网超市中的应用

超市一站式购物已进入城市的千家万户。然而人们在选购时却采用直接翻阅商品的方式&#xff0c;既不方便又不卫生甚至大大缩短食品类商品保质期&#xff0c;也给超市商品管理造成很大难度。物联网(The Internet of things)基于射频识别(RFID)、红外感应等技术&#xff0c;把物品…

CentOS环境下Nacos2.3集成PostgreSQL

title: CentOS环境下Nacos2.3集成PostgreSQL date: 2023-12-21 19:15:00 categories: Nacos description: CentOS环境下Nacos2.3集成PostgreSQL 1. 目录 1. 目录2. 简介3. 安装部署 3.1. 部署模式3.2. 环境准备3.3. 下载安装文件3.4. PostgreSQL插件 3.4.1. 下载地址3.4.2. 结…

面试心得总结ing版

1.rpc框架&#xff1f;常见的rpc框架组件&#xff1f;rpc框架与http框架的区别&#xff1f; rpc框架是远程服务调用框架&#xff0c;简单来说&#xff0c;就是在同一个网络下&#xff0c;服务a可以调用服务b中的某个接口。底层利用tcp协议&#xff08;传输层&#xff09;建立网…

VScode远程连接服务器,Pycharm专业版下载及远程连接(深度学习远程篇)

Visual Code、PyCharm专业版&#xff0c;本地和远程交互。 远程连接需要用到SSH协议的技术&#xff0c;常用的代码编辑器vscode 和 pycharm都有此类功能。社区版的pycharm是免费的&#xff0c;但是社区版不支持ssh连接服务器&#xff0c;只有专业版才可以&#xff0c;需要破解…

HTML网站基础

一、前端开发基础 前端一共三门语言——HTML、CSS、JS&#xff08;Java Script&#xff09; HTML用于静态网页框架&#xff0c;CSS用于修饰&#xff0c;JS构成动态网页 1、HTML 对于中文网页需要使用 <meta charset"utf-8"> 声明编码&#xff0c;否则会出现…

【论文阅读】MCANet: Medical Image Segmentation with Multi-Scale Cross-Axis Attention

文章目录 摘要创新点总结实现效果总结 摘要 链接&#xff1a;https://arxiv.org/abs/2312.08866 医学图像分割是医学图像处理和计算机视觉领域的关键挑战之一。由于病变区域或器官的大小和形状各异&#xff0c;有效地捕捉多尺度信息和建立像素间的长距离依赖性至关重要。本文提…

面向 AI,重塑云基础设施、存储、芯片、Serverless……2023亚马逊云科技re:Invent中国行

一年一度亚马逊云科技重要的技术盛会 re:Invent 刚落下帷幕&#xff0c;2023 亚马逊云科技 re:Invent 中国行就将其中重要的信息与内容带给了中国市场和用户。作为全球的云计算巨头&#xff0c;今年亚马逊云科技可以说全面加码 AI&#xff0c;例如发布完整的端到端生成式 AI 技…

人工智能_机器学习073_SVM支持向量机_人脸识别模型建模_预测可视化_网格搜索交叉验证最优化参数对比---人工智能工作笔记0113

接着上一节来说,可以看到我们已经找到了合适的参数,然后 我们可以看一下这里 gc.best_params_ 就可以打印出最合适的参数 然后我们把最合适串按说填入到代码中,然后进行计算,看看得分 可以看到得分,训练数据是1.0 然后测试数据得分是0.7857...对吧

2024深入评测CleanMyMac X4.14.6破解版新的功能

随着时间的推移&#xff0c;我们的Mac电脑往往会变得越来越慢&#xff0c;存储空间变得越来越紧张&#xff0c;这时候一个优秀的清理工具就显得尤为重要。作为一款备受好评的Mac清理工具&#xff0c;它能够为你的Mac带来全方位的清理和优化。在本文中&#xff0c;我们将深入评测…

【HarmonyOS开发】OpenHarmony如何实现⼀次开发,多端部署

OpenHarmony提供用户程序框架、Ability框架以及UI框架&#xff0c;能够保证开发的应用在多终端运行时保证一致性。一次开发、多端部署。 多终端软件平台API具备一致性&#xff0c;确保用户程序的运行兼容性。 HarmonyOS提供了用户程序框架、Ability框架以及UI框架&#xff0c;…

WebRTC概念

定义 一个实时通信标准 通话原理 媒体协商 在WebRTC中&#xff0c;参与视频通讯的双方必须先交换SDP信息&#xff0c;获得一个都支持的编码格式 网络协商 目的&#xff1a;找到一条相互通讯的链路 做法&#xff1a;获取外网IP地址映射&#xff0c;通过信令服务器交换“网…

华锐三维云展平台 | VR在线展览云平台提供定制化虚拟展厅制作工具

随着科技的飞速发展&#xff0c;互联网技术的不断革新&#xff0c;广州华锐互动顺应时代需求&#xff0c;开发了VR在线展览云平台&#xff0c;用户可以在平台上自主创建属于自己的3D展厅。VR在线展览云平台正改变着传统展览行业的模式&#xff0c;为参展者提供更高效、更便捷、…

vue3整合Element-Plus,极速上手。

条件分页查询&#xff1a; 需求分析&#xff1a; form表单 Button按钮 Table表格 Pagination分页 页面布局&#xff1a; 搜索表单&#xff1a; 如果表单封装的数据较多&#xff0c;建议绑定到一个对象中。 …

Hazel macOS自动化清理

Hazel是一款在Mac平台上的自动化文件管理工具&#xff0c;它可以帮助用户自动化处理文件&#xff0c;从而提高工作效率和减少重复性任务的时间和精力。以下是Hazel软件的功能特色&#xff1a; 强大的自动化处理功能&#xff1a;Hazel可以根据用户设定的规则&#xff0c;自动执…

Android---Kotlin 学习009

继承 在 java 里如果一个类没有被 final 关键字修饰&#xff0c;那么它都是可以被继承的。而在 kotlin 中&#xff0c;类默认都是封闭的&#xff0c;要让某个类开放继承&#xff0c;必须使用 open 关键字修饰它&#xff0c;否则会编译报错。此外在子类中&#xff0c;如果要复写…

Redis设计与实现之服务器与客户端

目录 一、服务器与客户端 1、初始化服务器 1. 初始化服务器全局状态 2. 载入配置文件 3. 创建 daemon 进程 4. 初始化服务器功能模块 5. 载入数据 6. 开始事件循环 2、 客户端连接到服务器 3、命令的请求、处理和结果返回 4、命令请求实例:SET 的执行过程 5、Redis服…

数据仓库【1】:简介

数据仓库【1】&#xff1a;简介 1、诞生背景1.1、数据仓库诞生原因1.2、历史数据积存1.3、企业数据分析需要 2、基本概述2.1、数据仓库&#xff08;Data Warehouse&#xff0c;DW&#xff09;2.2、数据仓库特点2.3、数据仓库 VS 数据库 3、技术实现3.1、数据仓库建设方案3.2、传…