散列算法和哈希表结构

散列算法和哈希表结构

算法概述
  • Hash ,一般翻译做“ 散列” ,也有直接音译为“ 哈希” 的,就是把任意长度的输入(又叫做预映射, pre-image ),通过散列算法,变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不 同的输入可能会散列成相同的输出,而不可能从散列值来唯一的确定输入值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。
哈希表
  • 数组的特点是:寻址容易,插入和删除困难;而链表的特点是:寻址困难,插入和删除容易。那么我们能不能综合两者的特性,做出一种寻址容易,插入删除也容易 的数据结构?答案是肯定的,这就是我们要提起的哈希表
  • 哈希表是一种典型的“空间换时间”的做法
  • 哈希表有多种不同的实现方法,我接下来解释的是最常用的一种方法—— 拉链法
  • HashMap其实也是一个线性的数组实现的,所以可以理解为其存储数据的容器就是一个线性数组,如图所示,从0连续到15。这可能让我们很不解,一个线性的数组怎么实现按键值对来存取数据呢?这里HashMap有做一些处理。
    • 首先HashMap里面实现一个静态内部类Entry 其重要的属性有 key , value, next,从属性key,value我们就能很明显的看出来Entry就是HashMap键值对实现的一个基础bean,我们上面说到HashMap的基 础就是一个线性数组,这个数组就是Entry[],Map里面的内容都保存在Entry[]里面。
    • 既然是线性数组,为什么能随机存取?这里HashMap用了一个小算法,大致是这样实现:
存储时:  

int hash = key.hashCode();--> 这个hashCode方法这里不详述,只要理解每个key的hash是一个固定的int值  

int index = hash % Entry[].length;  

Entry[index] = value;  

取值时:  

int hash = key.hashCode();  

int index = hash % Entry[].length;  

return Entry[index]
hash冲突
  • 如果两个key通过hash % Entry[].length得到的index相同,会不会有覆盖的危险?

    这里HashMap里面用到链式数据结构的一个概念.上面我们提到过Entry类里面有一个next属性,作用是指向下一个Entry。打个比方, 第一个键值对A进来,通过计算其key的hash得到的index=0,记做:Entry[0] = A.一会后又进来一个键值对B,通过计算其index也等于0,现在怎么办?HashMap会这样做:B.next = A,Entry[0] = B,如果又进来C,index也等于0,那么C.next = B,Entry[0] = C;这样我们发现index=0的地方其实存取了A,B,C三个键值对,他们通过next这个属性链接在一起。所以疑问不用担心。

  • 解决方法
    • 链地址法

      • 种方法的基本思想是将所有哈希地址为i的元素构成一个称为同义词链的单链表,并将单链表的头指针存在哈希表的第i个单元中,因而查找、插入和删除主要在同义词链中进行。链地址法适用于经常进行插入和删除的情况。
负载因子
  • 比如我们存储70个元素,但我们可能为这70个元素申请了100个元素的空间。70/100=0.7,这个数字称为负载因子。
常见hash算法
  • MD5
  • SHA-1 及其他
Hash构造函数的方法
  • 直接寻址法:取keyword或keyword的某个线性函数值为散列地址。即H(key)=key或H(key) = a?key + b,当中a和b为常数(这样的散列函数叫做自身函数)
  • .数字分析法:分析一组数据,比方一组员工的出生年月日,这时我们发现出生年月日的前几位数字大体同样,这种话,出现冲突的几率就会非常大,可是我们发现年月日的后几位表示月份和详细日期的数字区别非常大,假设用后面的数字来构成散列地址,则冲突的几率会明显减少。因此数字分析法就是找出数字的规律,尽可能利用这些数据来构造冲突几率较低的散列地址。
  • 平方取中法:取keyword平方后的中间几位作为散列地址。
  • .折叠法:将keyword切割成位数同样的几部分,最后一部分位数能够不同,然后取这几部分的叠加和(去除进位)作为散列地址。
  • 随机数法:选择一随机函数,取keyword的随机值作为散列地址,通经常使用于keyword长度不同的场合。
  • 除留余数法:取keyword被某个不大于散列表表长m的数p除后所得的余数为散列地址。即 H(key) = key MOD p, p<=m。不仅能够对keyword直接取模,也可在折叠、平方取中等运算之后取模。对p的选择非常重要,一般取素数或m,若p选的不好,easy产生同义词。
性能比较
  • 一般来说,使用 散列表 会比 红黑树 快很多。但具体还是要看 哈希函数 的计算效率。
  • 但是 散列表 无法保证顺序,所以如果你需要进行有关顺序的操作,应该使用 红黑树 或者 二叉搜索树 。

原文地址:https://www.cnblogs.com/frankltf/p/10346573.html

时间: 2024-10-25 07:39:00

散列算法和哈希表结构的相关文章

查找之散列查找(哈希表)

本学习笔记部分内容来自网易云课堂浙江大学数据结构课程,谢谢! 1.散列表(哈希表) 已知的几种查找方法: 顺序查找  O(N) 二分查找(静态查找)  O(logN) 二叉搜索树      O(h)  h为二叉树高度   (动态查找:有插入有删除有查找) 平衡二叉树      O(logN) 查找的本质:已知对象找位置 1.有序安排对象:全序或半序: 2.直接算出对象位置:散列. 散列查找法的两项基本工作: 1.计算位置:构造散列函数确定关键词存储位置: 2.解决冲突:应用某种策略解决多个关键词

对称密码、非对称密码、散列算法与PKI

对称密码.非对称密码.散列算法与PKI 密码学要解决的问题:机密性.完整性.身份验证(抗抵赖性): 一.对称密码: 对称密码技术:发件人和收件人使用其共同拥有的单个密钥 ,这种密钥既用于加密,也用于解密,叫做机密密钥(也称为对称密钥或会话密钥). 能够提供信息机密性(没有密钥信息不能被解密).完整性(被改变的信息不能被解密)的服务. 对称式密码学又称:单钥密码学.秘密密钥密码学.会话密钥密码学.私钥密码学.共享秘钥密码学  常见的对称式加密技术: DES(数据加密标准):分组式加密,算法源于Lu

48 容器(七)——HashMap底层:哈希表结构与哈希算法

哈希表结构 哈希表是由数组+链表组成的,首先有一个数组,数组的每一个位置都用来存储一个链表,链表的基本节点为:[hash值,key值,value值,next],当存入一个键值对时,首先调用hashcode()方法获得key的hashcode,然后通过算法计算出hash值,当不同的key取到相同的hash值时,后面的key作为一个节点连接到前一个相同hash值的key的节点. hash值的算法 最差的算法:hashcode/hashcode 会将所有的元素存储在数组的下标1位,实际上已经退化为一个

Java哈希散列算法简介 - MD5 &amp; SHA-512

Java哈希散列算法简介 - MD5 & SHA-512 在日常的开发工作中,我们常常会碰到这样的一个场景:我们需要有一种可靠的行之有效的方法来检验跟判断数据在传输过程当中的完整性.最常见的一种情况就是当我们传输文件的时候,由于网络故障或者其他的一些因素,可能会出现我们下载下来的文件不完整,这给我们日常的开发和维护带了一些难题:另外的一个较为常用的场景就是:有没有一种行之有效的方法让我们可以很方便的判断服务器上的文件是不是有最新的数据更新,比如我们现在的移动Hybird App开发,我们经常会发

Nginx 哈希表结构 ngx_hash_t

概述 关于哈希表的基本知识在前面的文章<数据结构-哈希表>已作介绍.哈希表结合了数组和链表的特点,使其寻址.插入以及删除操作更加方便.哈希表的过程是将关键字通过某种哈希函数映射到相应的哈希表位置,即对应的哈希值所在哈希表的位置.但是会出现多个关键字映射相同位置的情况导致冲突问题,为了解决这种情况,哈希表使用两个可选择的方法:拉链法 和 开放寻址法. Nginx 的哈希表中使用开放寻址来解决冲突问题,为了处理字符串,Nginx 还实现了支持通配符操作的相关函数,下面对 Nginx 中哈希表的源码

MD5(单向散列算法)原理分析

注:本文章转载于网络. MD5(单向散列算法)的全称是Message-Digest Algorithm 5(信息-摘要算法),经MD2.MD3和MD4发展而来.MD5算法的使用不需要支付任何版权费用. MD5功能:    输入任意长度的信息,经过处理,输出为128位的信息(数字指纹):    不同的输入得到的不同的结果(唯一性):    根据128位的输出结果不可能反推出输入的信息(不可逆): MD5属不属于加密算法:    认为不属于的人是因为他们觉得不能从密文(散列值)反过来得到原文,即没有

Java数据结构和算法之哈希表

五.哈希表 一般的线性表.树中,记录在结构中的相对位置是随机的即和记录的关键字之间不存在确定的关系,在结构中查找记录时需进行一系列和关键字的比较.这一类查找方法建立在"比较"的基础上,查找的效率与比较次数密切相关.理想的情况是能直接找到需要的记录,因此必须在记录的存储位置和它的关键字之间建立一确定的对应关系f,使每个关键字和结构中一个唯一的存储位置相对应.因而查找时,只需根据这个对应关系f找到给定值K的像f(K).若结构中存在关键字和K相等的记录,则必定在f(K)的存储位置上,由此不需

数据结构与算法实例(哈希表实现)

数据结构与算法(哈希表) 哈希函数:在记录的关键字与记录的存储地址之间建立的一 种对应关系叫哈希函数. 哈希函数是一种映象,是从关键字空间到存储地址空间的一 种映象.可写成:addressi=H(keyi) ,其中i是表中某 个元素. 哈希表:应用哈希函数,由记录的关键字确定记录在表中的 地址,并将记录放入此地址,这样构成的表叫哈希 ★哈希表的特点就是数据与其在表中的位置存在相关性,也就是有关系的,通过数据应该可以计算其位置,哈希表最大的特点是是可以快速实现查找,插入和删除.因为它独有的特点,H

加密散列算法——MD5

引用wiki的定义,散列函数(或散列算法,英语:Hash Function)是一种从任何一种数据中创建小的数字"指纹"的方法.该函数将数据打乱混合,重新创建一个叫做散列值的指纹.散列值通常用来代表一个短的随机字母和数字组成的字符串.好的散列函数在输入域中很少出现散列冲突.在散列表和数据处理中,不抑制冲突来区别数据,会使得数据库记录更难找到.(具体专业术语请自行度娘) MD5是单向散列算法的一种,全称是Message-Digest Algorithm 5(信息-摘要算法),经MD2.MD