数据结构与算法(五)

news2024/11/22 21:46:55

哈希表(hash)

 

什么是hash?

散列,是把任意长度的输入通过散列算法变换成固定长度输出,该输出的值就是散列值。这种转换是一种压缩映射。映射表达的是一一对应的关系,也就是说,散列值的空间通常会小于输入空间。

const md5 = require('md5-node');
const password = 12345;
console.log(md5(password));

哈希算法不能从结果去推断输出,也就是说哈希算法是不可逆的。

哈希特性

  1. 不可逆,可以作为加密算法存在。   
  2. 计算极快

MD5是不可逆的。对比方式进行校验,(web安全:彩虹表)

哈希用途

  1. 密码
  2. 文件完整校验

数组的不足:

如果是基于索引,数组性能好,但如果基于内容,性能就比较低(插入删除:链表性能好;查询修改:数组性能好)。

举个栗子

有800个好友,设计一个数据结构存储好友信息,名字、邮箱地址

链表查询慢,每次必须从头到尾遍历,用数组需要索引,增加id

const friend = [

{ id:1,name:'张三' ,email:'123@qq.com'},

{ id:2,name:'李四' ,email:'456@qq.com'},

]

有没有一个方法可以将名字直接作为索引提升查询速度?

将字符串name转换成数组的索引,这种东西叫哈希表

哈希表通常是基于数组时限的,但相对于数组,优势:

它可以提供非常快的插入-删除-查找操作(哈希表的结构:数组,但是它和数组不同的是哈希表对于索引一种转换,我们称之为哈希函数)

例如:单词如何转化数字编码?

ASCLL码,编码方式可将字符转化成数字

哈希表是以键值对存储的数据结构,哈希表的键是经过散列函数计算出来的;每一个关键码对应一个值,我们把这种以关键码 -> 值的形式存储数据的数组称为哈希表(散列表)

最简单的哈希函数:把ascll 码加在一起,取模一个数字,最后模出来是多少就是多少(取余数)

class HashTable {
	constructor(){
		// 创建哈希表
		this.table = []; 
	}
	loseHashCode(key){
		let hash = 0 ;
		for(let i=0;i<key.length;i++){
			// 计算KEY unicode码
			hash += key[i].charCodeAt();
		}
		// 取模 37质数,很大程度上避免碰撞
		return hash % 37;
	}
	// 新增元素
	put( key ,value ){
		// 获取key
		const position = this.loseHashCode(key);
		this.table[position] = value;
	}
	// 移除元素
	remove(key){
		this.table[this.loseHashCode(key)] = undefined;
	}
	// 获取元素
	get(key){
		return this.table[this.loseHashCode(key)];
	}
}
const hashtable = new HashTable();
hashtable.put('小白','123@qq.com');
console.log(hashtable);

哈希覆盖

数组里面,下标相同,数据覆盖,哈希表一样,对于不同要存储的数据经过哈希函数的得到的索引有可能相同。

解决方法:

链地址法

开放地址法:

开放地址法是一种解决数据存放冲突的方法,常用的有线性探测、二次探测和再哈希法

线性探测法

寻找空白的位置来放置冲突的数据项

插入的时候,发现原来index位置已经从存储,则从index+1往后找寻空位置 ,进行插入

查询的时候,查找到空位置就结束,不会查询整个表

删除的时候,不可以设置为NULL。

但是弊端:聚集(一连串填充单元)

当哈希表越来越满时聚集越来越严重,这导致产生非常长的探测长度,后续的数据插入将会非常费时。通常数据超过三分之二满时性能下降严重,因此设计哈希表关键确保不会超过这个数据容量的一半,最多不超过三分之二。

聚集会影响哈希表的性能,无论hi插入、删除、查询

二次探测法

查询优化算法

二次探测是过程是x+1,x+4,x+9,...

二次探测的步数是原始位置相隔的步数的平方

 二次探测可以消除在线性探测中产生的聚集问题,但是二次探测还是会产生一种更明确更细的聚集。二次聚集的产生是在二次探测的基础上产生的现象。例如N个数据经hash函数计算后都映射到到数组下标10,探测第二个数字需要以一步长,第三个数字需要以4步长为单位,第四个数字则需要以九为步长。好在二次探测并不常用,解决聚集问题还是有一种更好的办法:再哈希法。

再哈希法

再哈希是把关键字用不同的哈希函数再做一遍哈希化,用这个结果作为步长,对指定的关键字,探测的步长是不变的,可以说不同的关键字可以使用不同的步长,并且步长可以控制。一般来说,再哈希函数可以采用以下这种:

stepSize=constant-(key%constant);

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

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

相关文章

[算法前沿]--014-DeepSpeed-Chat 模型训练实战<下>

文章目录 1.实战Step1:监督微调1.1 任务说明: 使用标定的数据对预训练模型进行微调评价与测试:2 实战Step2:Reward模型微调3.实战Step3:RLHF训练3.评价与测试4.QA参考1.实战Step1:监督微调 基础语言模型是指只在大规模文本语料中进行了预训练的模型,未经过指令和下游任务…

淘宝商品历史价格API接口 调用说明及功能介绍

淘宝商品历史价格API是一款可以帮助用户获取淘宝商品历史价格数据的接口。通过该接口&#xff0c;用户可以轻松地获取某个商品在过去一段时间中的价格趋势和波动情况&#xff0c;以便更好地了解该商品的市场走势和价值变化情况。 该API具备以下功能&#xff1a; 1. 支持多种查…

对于大流量请求的处理方案(NATNginx)

情况描述&#xff1a; 如图所示&#xff0c;厂家的A服务器&#xff0c;到客户的C服务器不通&#xff0c;需要我这边通过B服务器做一次流量转发。 由于&#xff0c;每次请求数据流都太大&#xff0c;怕HTTPS方式&#xff0c;会出现请求超时&#xff0c;断开连接。 解决方案&am…

什么是自动化测试框架?我们该如何搭建自动化测试框架?

无论是在自动化测试实践&#xff0c;还是日常交流中&#xff0c;经常听到一个词&#xff1a;框架。之前学习自动化测试的过程中&#xff0c;一直对“框架”这个词知其然不知其所以然。 最近看了很多自动化相关的资料&#xff0c;加上自己的一些实践&#xff0c;算是对“框架”…

Codeium:一个免费的、支持70多种编程语言的、可以与你对话的智能编程助手,让你从繁琐的代码中解放出来

摘要 Codeium&#xff1a;免费的人工智能代码加速工具&#xff0c;让编程变得更简单、更快、更有趣 如何使用Codeium来提高编程效率和质量&#xff1f;一篇文章教你掌握Codeium的三大功能&#xff1a;代码完成、聊天和搜索 Codeium vs GitHub Copilot&#xff1a;哪个更适合你…

Linux的软件生态与两个方面,客户端/Linux软件下载安装的认识,yum源/仓库(repo)与yum指令的本质,yum指令操作等

铺垫1&#xff1a;服务器属于硬件 服务器是一种计算机硬件设备&#xff0c;主要用于存储、管理和处理数据以及为其他计算机提供服务。服务器通常具有高性能的处理器、大容量的硬盘、大内存和高速网络连接等特点&#xff0c;可以提供各种服务&#xff0c;如网站托管、电子邮件服…

【教程】对视频平台授权时,加密机设备如何固定IP?

我们在此前的文章中也介绍过&#xff0c;我们的视频平台都是通过加密机、加密狗、激活码三种方式进行服务授权的&#xff0c;其中&#xff0c;加密机使用得较多。具体注意事项可以查看这篇文章&#xff1a;加密机授权注意事项汇总及解决方法。 加密机在使用时&#xff0c;需要在…

bat操作git(一键提交)

添加环境变量&#xff1a;D:\Git\Git\cmd 环境变量添加完毕后就可以直接在命令框使用git命令了 脚本实现 实现一键完成远程仓库的更新 echo off git add . git commit -m "daily push data-structure-and-algorithms" git push echo push respostory successful…

python包之matplotlib基础概念和代码详解

1 基础概念 Figure&#xff1a; 可以理解为 canvas(画布)&#xff0c;在画布上可以展示一个或多个Axes Axes&#xff1a;中文翻译为轴&#xff0c;但与数学中的概念不同&#xff0c;Axes可以理解为子画布&#xff0c;它属于Figure。也可以理解为它就是一个图形或绘制图形的区…

为什么有了IP地址,还需要MAC地址呢?

不知道大家有没有困惑&#xff1a;为什么有了IP地址&#xff0c;还需要MAC地址呢&#xff1f;他们之间到底有什么联系&#xff1f;又有什么区别&#xff1f;是不是有一个是多余的&#xff1f; 流言传到了“IP地址”和“MAC地址”的耳朵里&#xff0c;他俩也非常苦恼&#xff0c…

【Unity】 UI自适应案例

UI自适应案例 案例一:背包自动布局1. 创建背包面板2. 背包子项自动布局3. C#代码:动态添加子项到背包中案例二:文字自适应高度1. 创建文字面板2. 组件基本设置3. C#代码:动态更新文字并自适应高度案例一:背包自动布局 需求:动态添加背包组件,设定每行特定个数并自动匹配…

抖音seo矩阵系统源码开发(三)

抖音seo框架分析&#xff1a; 抖音SEO源码主要有两种框架&#xff1a; 一是基于爬虫的框架&#xff0c;通过爬取抖音平台的内容&#xff0c;提取关键词和标签等信息&#xff0c;再结合优化技巧&#xff0c;最终实现SEO效果的提升&#xff1b;二是基于粉丝互动和品牌策划的框架…

制作iOS越狱deb插件+dpkg命令行教程

iOS越狱deb插件的制作 dpkg命令行教程 deb安装包的制作 介绍 Cydia Sileo都是基于Debian开发的, 所以插件都是打包成.deb格式 deb包是Debian软件包格式&#xff0c;文件扩展名为.deb。是Debian系统(包含Debian和Ubuntu等)专属安装包格式。 deb包在Linux操作系统中类似于wi…

探索小程序容器在软件应用架构中的角色和优势

今年来&#xff0c;随着软件及开源技术的发展&#xff0c;软件应用架构的概念也随之流行起来。它提供了一种组织和设计软件系统的有效方法&#xff0c;具有许多优势和好处&#xff1a; 模块化和可维护性&#xff1a;软件应用架构将系统拆分为模块化的组件&#xff0c;每个组件负…

00后实在太卷了,测试用例写的比我还好,羞耻啊.....

经常看到无论是刚入职场的新人&#xff0c;还是工作了一段时间的老人&#xff0c;都会对编写测试用例感到困扰&#xff1f;例如&#xff1a; 如何编写测试用例&#xff1f; 作为一个测试新人&#xff0c;刚开始接触测试&#xff0c;对于怎么写测试用例很是头疼&#xff0c;无…

面了一个5年经验的测试工程师,自动化都不会也敢喊了16k,我也是醉了····

在深圳这家金融公司也待了几年&#xff0c;被别人面试过也面试过别人&#xff0c;大大小小的事情也见识不少&#xff0c;今天又是团面的一天&#xff0c; 一百多个人都聚集在一起&#xff0c;因为公司最近在谈项目出来面试就2个人&#xff0c;无奈又被叫到面试房间。 整个过程…

【JavaEE进阶】——第七节.Spring AOP统一功能处理(切面、切点、连接点、通知)

作者简介&#xff1a;大家好&#xff0c;我是未央&#xff1b; 博客首页&#xff1a;未央.303 系列专栏&#xff1a;JavaEE进阶 每日一句&#xff1a;人的一生&#xff0c;可以有所作为的时机只有一次&#xff0c;那就是现在&#xff01;&#xff01;&#xff01; 文章目录 前…

教学场景下的AI数字人,可视化语音交互

玩了Midjourney&#xff0c;感慨AI太强大了&#xff0c;设计师已哭晕~~ AI数字人 教学场景下的AI数字人&#xff0c;能实现什么&#xff1f; 图&#xff1a;AI数字人 图&#xff1a;AI数字人 个性化学习支持 根据学生的个人需求和学习风格&#xff0c;提供个性化的学习支持和…

(赠书活动第2期)Java生日快乐,“不读此生遗憾”的Java开发必备书单

Java诞生日&#xff0c;推荐Java“此生错过必遗憾”系列书单 Java28岁了&#xff0c;当打之年&#xff0c;并且还会打很多年。 为即将或正在使用Java的你推荐Java“此生错过必遗憾”系列书单。看看你还缺哪本&#xff1f;请补齐。优惠购书链接就在文中&#xff0c;拿好不谢。 …

【权限提升】Linux Kernel 权限提升漏洞 (CVE-2023-32233)

文章目录 前言声明一、漏洞描述二、影响版本三、本地复现四、修复方案 前言 Linux Netfilter 是一个在 Linux 内核中的网络数据包处理框架&#xff0c;也称作 iptables&#xff0c;它可以通过各种规则和过滤器&#xff0c;基于数据包的来源、目标地址、协议类型、端口号等信息…