开局一张图帮你充分理解哈希表(散列表)
目录
1哈希表的概念:
1.1哈希表的插入图示:
1.2哈希表的查询图示:
2.哈希冲突
2.1哈希冲突的概念:
2.2避免冲突
2.2.1哈希函数设计
2.2.2负载因子的调节
3.解决冲突
3.1闭散列:
3.2开散列/(哈希桶)
4.哈希表的实现
1哈希表的概念:
1.1哈希表的插入图示:
1.2哈希表的查询图示:
上图解释了如何以哈希的方式存储数据了;那么数据该如何读取呢?请看下图!
2.哈希冲突
2.1哈希冲突的概念:
2.2避免冲突
哈希表底层数组的容量往往是小于实际要存储的关键字的数量的,这也就导致了一个问题,那就是冲突是必然会发生;虽然冲突是必然发生的;但是我们能做到的是尽量降低冲突的概率.
如何有效避免哈希冲突呢?从以下两个方面入手:哈希函数的设计,负载因子的调节!
2.2.1哈希函数设计
哈希函数设计不合理是引起哈希冲突的一个重要原因;那么常见的哈希函数主要是以下两种!
1. 直接定制法:
2. 除留余数法:
2.2.2负载因子的调节
负载因子的定义: a = 填入表中的元素个数 / 哈希表的长度
通俗的理解就是:当哈希表长度一定时;随着插入表中元素的增加;负载因子(a)就会增大;而负载因子越大,冲突产生的概率就越大;所以我们可以通过降低负载因子来降低冲突率.
负载因子与冲突率的关系如下:
那么怎么调节负载因子呢?
由定义公式可知:a = 填入表中的元素个数 / 哈希表的长度;
我们可以通过增大分母来使负载因子a降低;也就是将哈希表的长度增长,通俗的讲:将数组扩容;
3.解决冲突
解决哈希冲突两种常见的方法是:闭散列和开散列
3.1闭散列:
虽然是线性探测解决了寻找空位的问题,但是又引来了另一个问题:那就是会使产生冲突的数据堆积在一块,这与其找下一个空位置有关系,因为找空位置的方式就是挨 着往后逐个去找,因此二次探测为了避免该问题.
2.二次探测:找下一个空位置的方法为:H(i) = (H0 + i^2 ) % m, 或者:H(i)= (H0 - i^2) % m。其中:i = 1,2,3…, 是通过散列函数Hash(x)对元素的关键码 key 进行计算得到的位置,m是表的大小。(通俗的理解就是:虽然也是找空位插入,但是在找空位的时候,跟上一个找的位置隔的更远了,也就使的冲突的数据分的更加开了)
3.2开散列/(哈希桶)
4.哈希表的实现
public class HashBucket {static class Node {public int key;public int val;public Node next;public Node(int key, int val) {this.key = key;this.val = val;this.next = null;}}private Node[] array;public int usedsize;public HashBucket() {this.array = new Node[10];this.usedsize = 0;}public void put(int key, int val) {//1.确定下标==哈希函数int index = key % this.array.length;//2.遍历这个下标的链表Node cur = array[index];//头插法while (cur != null) {//如果key已经存在 更新valif (cur.key == key) {cur.val = val;return;}cur = cur.next;}//3.cur == null 当前数组下标下的链表 没有key 则将其以头插法进行插入Node node = new Node(key, val);node.next = array[index];array[index] = node;this.usedsize++;//4.判断是否需要扩容if (loadFactor() >= 0.75) {//扩容resize();}}public double loadFactor() {return this.usedsize * 1.0 / this.array.length;}public void resize() {//自己创建新的数组 该数组是原本数组长度的两倍Node[] newArray = new Node[2 * this.array.length];//需要把原本数组里所存储的数据全部重新进行哈希 因为数组的长度变了 哈希函数里的数值就变了 所以需要重新哈希//遍历原本的哈希桶//最外层循环 控制数组的下标for (int i = 0; i < array.length; i++) {Node cur = array[i];Node curNext = null;while (cur != null) {//记录cur.nextcurNext = cur.next;//重新确立新的下标 然后进行头插法int index = cur.key % newArray.length;cur.next = newArray[index];newArray[index] = cur;cur = curNext;}}this.array = newArray;}public int get(int key) {//以什么样的方式存储的 就以什么样的方式取出int index = key % this.array.length;Node cur = array[index];while (cur != null) {if (cur.key == key) {return cur.val;}cur = cur.next;}return -1;}
}
开局一张图帮你充分理解哈希表(散列表)相关推荐
- 7个GIF动图帮你瞬间理解三角函数
7个GIF动图帮你瞬间理解三角函数 蝌蚪五线谱 百家号04-2120:53 图片来源:IMGUR 三角函数是数学中研究三角形的一个分支,专门阐述三角形的角度和对应边的关系. 有趣的是,定义边角关系的三 ...
- 【JavaScript】JavaScript模拟实现面向对象一张图帮助你深刻理解原型链和原型对象
文章目录 一.JavaScript模拟面向对象 1.函数是类 2.函数中各种变量的声明 3.关于函数内的this 小结:JavaScript中函数是什么? 4.练习:面向对象思想编写Complex类 ...
- 一张图帮你看懂 iPhone 6 Plus 的屏幕分辨率
一张图帮你看懂 iPhone 6 Plus 的屏幕分辨率 几天前发布的 iPhone 6 Plus 官方标称屏幕是 1920 x 1080 的,但是在 Xcode 中我们发现模拟器的屏幕其实是看似奇怪 ...
- 几张图帮你捋清“中国金融机构体系”
原文链接:几张图帮你捋清"中国金融机构体系" - 走看看 (zoukankan.com) 几张图帮你捋清楚,中国金融机构的关系- 金融业务有哪些? 金融业务有:银行业.证券业.保险 ...
- 几张图帮你理解 docker 基本原理及快速入门
http://hainiubl.com/topics/13 什么是docker Docker 是一个开源项目,诞生于 2013 年初,最初是 dotCloud 公司内部的一个业余项目.它基于 Goog ...
- 一张图帮你记忆,Spring Boot 应用在启动阶段执行代码的几种方式
点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 前言 有时候我们需要在应用启动时执行一些代码片段,这些片 ...
- 三次简化一张图:一招理解LSTM/GRU门控机制
机器之心专栏 作者:张皓 RNN 在处理时序数据时十分成功.但是,对 RNN 及其变种 LSTM 和 GRU 结构的理解仍然是一个困难的任务.本文介绍一种理解 LSTM 和 GRU 的简单通用的方法. ...
- 一张图30分钟带你入门python-大数据时代来了!神级程序员一张图帮你梳理Python脉络,快速入门...
python语言是我目前为止用的最爽的语言,因为它真的很优美.虽然c,c++,java也非常的强大和伟大,但是每一种语言伟大的背后都是有一定的时代背景. 在PC时代大量的嵌入式的设备,底层的代码,以及 ...
- 一张图就让你理解K-Means算法!!
K-Means是无监督学习中最经典的聚类算法 一.什么是无监督学习?什么是聚类? 无监督学习简单来说就是没有标签变量,即没有y值,仅仅依靠特征变量x进行学习.通常以"是否有标签变量y&quo ...
最新文章
- 是时候装逼了,试试 IDEA 解决 Maven 依赖冲突的高能神器!
- 话说Ubuntu和FreeBSD将要合成一个新的版本:UbuntuBSD
- CTabCtrl - 如何使用TabCtrl控件
- 将构件发布到私有的nexus maven 仓库
- [wikioi]奇怪的梦境
- python识别出蓝色_OpenCVPython——无法检测蓝色对象
- Git——创建版本库【git init】
- 3.4 神经网络概述、tensorflow2实现——python实战
- 《图解HTTP》读书笔记(二:各种协议与HTTP协议之间的关系)
- c语言printf * abd bc,C语言练习题_答案版本
- mvc:annotation-driven:注解驱动
- WordPress付费资源素材下载主题 总裁CeoMax主题
- android:ems 属性
- 网络神采关键词过滤NET插件
- 32位与64位CPU字长
- js 监听esc按键
- [arch Linux] 使用grub实现Linux和Windows双系统的引导
- 计量经济学计算机数据分析,如何用计量经济学作实证分析..doc
- WPF 改进 WrapPanel 右侧填充
- 汇编语言里 eax, ebx, ecx, edx, esi, edi, ebp, esp这些都是什么意思啊? [
热门文章
- 列表xcode项目下所有的lnfo.plist
- 苹果cms重复采集重名视频解决方法
- 10.24程序员节疑问:沈从文的编程功底应该很厉害吧?
- 在线视频地址 ios播放在线视频
- 一周热图|王珞丹创立宠物用品品牌;超模何穗亮相雀巢冷萃自由大秀;乐高试点有声与盲文拼搭指南...
- matlab绘制分段函数,二维函数
- 几个Android云测试
- css怎么随着鼠标移动,利用CSS sprites制作随着鼠标移动的动画背景
- 电动车锂电池行业前景广阔,啰马锂服帮助企业、门店“降本增效”
- 2021年上半年最接地气的Android面经,隔壁都馋哭了