散列表(哈希表)

概述

什么是散列表? 如果说起它的另一个名字, 你一定很熟悉, 它的英文叫"Hash Table", 哈希表, 很熟悉吧.

散列的思想, 其实就是利用数组的随机访问特性, 将key-value形式的数据, 其中的key转换成数组下标, 即可实现将其存放到数组中, 进而实现随机访问.

而其中将key转换成数字的函数, 被称为散列函数, 或哈希函数.

为了方便大家看, 以下统一称为哈希, 知道这俩是一回事就行.

哈希函数

设计一个哈希函数, 有如下三点要求:

  1. 散列函数计算得出的值是一个正整数(数组下标嘛)

  2. 若key相等, 则计算后的哈希值相等

  3. 若key不相等, 则计算后的哈希值不相等

后面两点, 说白了就是, 计算后的哈希值是唯一的, 不变的.

要想达到第二点要求, 应该不难, 只要算法固定, 输入与输出就应该是固定的嘛

但是, 要想实现第三点, 就不一样了, 要想找到一个完全符合的, 几乎是不可能. 而且, 要想将其放到数组中, 数组的大小是有限的啊, 所以, 当出现计算后两个哈希值相等的情况, 就是哈希冲突.

哈希冲突

既然没有完美的哈希函数, 那么就不可避免会发生哈希冲突, 那么就要解决哈希冲突, 常用的有开放寻址法和链表法.

1. 开放寻址法

开放寻址法的思想很简单, 当发生哈希冲突的情况时, 就从当前位置往后找, 找到第一个空缺的位置放入.

对于开放寻址法, 查找操作也顺理成章, 计算key的哈希值后, 查看其下标元素是否为要寻找的元素, 若不是, 向后寻找, 一直找到出现空位, 则说明key不在表中.

但是, 删除操作就比较麻烦了, 因为查找是通过空位来判断的, 若直接删除key, 就会在下次查找时出现空位而打断本来应该继续的查找. 对于这种情况, 我们可以将删除的空位标记为delete, 查找时遇到delete不会中断就好了.

上面说的这种查找方法叫线性探测法, 顾名思义, 就是一个一个往后找, 另外还有两种经典查找方法: 二次探测和双重散列.

二次探测: 线性探测每次探测的步长(每次往后找的个数)是1, 也就是说探测的下标是k+0,k+1,k+2,k+3. 二次探测就是每次访问的步长变为原来的二次, 探测的下标为: k+0,k+1,k+2,k+9

双重散列: 就是不单单使用一个哈希函数, 而是使用一串, 当第一个哈希函数发生冲突时, 就用第二个计算, 再冲突, 再用第三个计算, 直到找到空位

问题

很明显, 开放寻址法有很大的问题. 当表中数据越来越多的时候, 哈希冲突的概率也会越来越大, 对应的查找操作也就会越来越慢, 甚至最终会遍历整个表.

装载因子

用装载因子来表示哈希表中空位的多少, 其计算公式是:

装载因子=表中元素个数 / 表的长度

装载因子越大, 说明空位越少, 冲突越多, 哈希表的性能越低.

2. 链表法

使用链表法来解决哈希冲突相对来说更为常见一些, Java中的HashMap就是这么处理的.

通过一张图来简单说明链表的处理方法:

当发生哈希冲突时, 将数据插入到对应的链表中. Java中的HashMap就是通过hashcode方法计算数组下标, 再通过equals方法判断两对象是否相等.

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

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

相关文章

如何让nRF52840 dongle化身为BLE sniffier (过程详细记录)

参考链接: How to install BLE Sniffer on nRF52840 Dongle and run it – Jimmys thing 软件环境: Windows 10Python v3.6 or later: 安装地址:Python Releases for Windows | Python.orgWireshark v2.4.6 or later: 安装地址:Wireshark DownloadnRF Connect: 安装地址: n…

哈希算法的用途

什么是哈希算法 一说到哈希算法, 我瞬间就想到了哈希函数、哈希表, 其实他们并不是一回事. 简单来说, 哈希算法就是将任意长度的字符串通过计算转换为固定长度的字符串, 不对, 不光字符串, 应该说是将任意长度的二进制串转换为固定长度的二进制串, 这个转换的过程就是哈希算法…

解决/mnt中有hgfs无共享文件

问题: 已经设置了共享目录,进入 /mnt/hgfs 文件夹,但发现提示没有共享的文件夹 使用以下办法解决(root权限): 解决: 1. 切换到root权限 sudo passwd root 2. 查看当前有哪些共享的目录 vmware-hgfsclient 3.进行挂…

贪婪算法回顾

回顾 还记的贪婪算法么? 如果你不记得了, 看了下面这个例子你一定会想起来, 因为这个例子太普遍了, 几乎每个将贪婪算法的地方, 第一个例子都是它, 言归正传. 问题: 现在有如下课程表, 要将这些课尽可能多的安排在教室A内. 课程名开始时间结束时间语文课9:0010:00数学课9:3…

【安全】基础概念梳理-基本加密方式、数字签名、证书

一、两种基本加密方式 1.1 对称加密 对称加密是指双方持有相同的密钥进行通信,加密速度快。常见的对称加密算法有DES、3DES、AES等。存在问题:通信双方如何获得相同的密钥? 1.2 非对称加密 非对称加密,又称为公开密钥加密&#…

PHP 自动加载

回顾 开始的时候, 如果想在一个php文件中使用其它文件的类或方法, 需要通过include/require方法将文件包含进来. 这种方法的缺点也很明显: 如果需要引入很多文件, 就需要很多的include语句, 不仅不美观, 而且也难免会又遗漏如果多个文件中定义了相同名称的常量, 会导致抛出重…

【坑】云相关

1. NAT NAT(Network Address Translation,网络地址转换:当在专用网内部的一些主机本来已经分配到了本地IP地址(即仅在本专用网内使用的专用地址),但又想和因特网上的主机通信(并不需要加密&…

Pycharm 2019 添加 docker 解释器

打开docker的tls 点击设置: 搜索docker, 添加: 点击解释器选项 添加 选择docker 这里说缺少映射, 先不管 接下来, 创建一个新项目, 在选择解释器的时候, 如果选择刚刚添加的, 会报错, 先选一个能用的, 进到项目再换 在右下角的解释器小部件, 选择我们刚刚添加的 然后就可以正常…

【待补】Wireshark+BLE dongle: BLE数据包捕获以及分析

文章目录前言1. 捕获BLE数据包2. 分析BLE数据包2.1 过滤掉不感兴趣的BLE数据包2.2 利用Wireshark内嵌工具生成图表前言 硬件:Nordic 52840 dongle 软件: Wireshark 1. 捕获BLE数据包 待补充。 2. 分析BLE数据包 2.1 过滤掉不感兴趣的BLE数据包 以自…

js动态添加div

问题 有没有遇到过这样的需求, 在页面上会有不定个input, 点击添加按钮就添加 每次写这玩意好麻烦啊, 把他封装起来, 需要的时候调用就好了 思路 因为每个input标签的name如果相同的话, 在后端接收的时候会出错, 所以我的解决办法就是在name后加上一个数字, 后端用一个循环进…

【坑】Sketch算法——Count-Min Sketch和Universal Sketch

文章目录参考链接一、Sketch算法用来做什么?二、Min-count sketch基础思想:进阶:特点:三、Universal Sketch参考链接 [1] Count-Min Sketch: https://blog.csdn.net/pipisorry/article/details/64126199 [2] Cormode G, Muthukrishnan S. An improved …

css中的单位

前端开发中, 做适配是少不了的, 这就用到了css中的各种长度单位, 做一下总结 在css中, 长度单位分为以下几种 绝对单位: px、in、cm、mm、pt、pc百分比单位: vw、vh、vmin、vmax、%相对单位: em、rem、ex、ch 各单位介绍 px 不用过多介绍, 精确像素 in 寸 cm 厘米 mm…

【5G入门】MCS调制编码方案简介

​ 目录参考资料:1. MCS简介MCS是什么如何选择MCS有哪些MCS可供选择如何配置MCS示例参考资料: 链接: 5G NR Modulation and Coding Scheme – Modulation and Code Rate. 1. MCS简介 MCS是什么 MCS(Modulation and Coding Scheme&#xf…

caffe初体验

caffe是一个深度学习的框架, 具体我也不太清楚, 可以自行百度吧, 我也是刚刚知道有这么一个框架, 才疏学浅啊. 在安装完caffe, 我的第一个想法就是, 别管他是个啥东西, 总得先让我运行一些看一看吧. 刚好, 官方就准备了一些数据, 供我们运行一下看一看使用. 因为我是通过dock…

【安全】进阶的Mosquitto:搭建一个安全的MQTT服务

目录一、基础版Mosquitto安装及运行Mosquitto安装Mosquitto运行二、基础安全版Mosquitto安装及运行(需要输入密码)Mosquitto安装Mosquitto配置Mosquitto测试效果三、安全版Mosquitto安装及运行Mosquitto安装TLS安装Mosquitto配置Mosquitto测试效果注意一…

PHP注释标记整理

什么是注释标记 我们在平常写代码或看别人写的代码时, 在方法的说明注释中经常会有这样的注释: /*** param $num* return array*/上面的*param* return 就是注释标记 注释标记用于生成文档, param指明需要接收的参数, return指明返回值 在使用 phpDocumentor 等工具生成文档…

PHP 循环引用的问题

问题 为了引出问题, 先来看下面一段代码: <?php $arr [a, b,c, d, ];foreach ($arr as &$each){echo $each; } echo PHP_EOL; foreach ($arr as $each){echo $each; }这段代码很简单, 输出数组的元素两次, 感觉会输出两次 abcd? 不好意思, 输出结果如下:  是不是感…

redis常规命令记录

概述 因为redis是单线程执行&#xff0c;所以不用关心并发问题。 简单记录一下redis的操作命令&#xff0c;留作查阅&#xff0c;回头再整理一下事物等操作。 reids中存储的是kev-value形式, 其中的value有几种: 字符串: 就是简单的string 字符串列表: 有序可重的列表 字符…

代码整洁之道-函数

什么是一个好的函数或者叫方法&#xff0c;只要能让函数明确的表达其意图&#xff0c;让读者能够一眼看出是一个怎样的函数&#xff0c;其接收什么参数&#xff0c;返回什么结果&#xff0c;做了什么事情。能做到这&#xff0c;大概就能算作一个好的函数了&#xff0c;看上去很…

代码整洁之道-格式

对于代码的格式&#xff0c;每个人都有不同的代码风格&#xff0c;这没什么。但是对于一个团队来说&#xff0c;最好能够统一代码风格&#xff0c;在同一个项目中&#xff0c;如果到处充斥着不同的代码风格&#xff0c;相比读起来并不是那么让人舒适&#xff0c;比如在什么地方…