哈希算法相关解析

1、散列法(哈希算法)

//原理:
一种高效的存储方式,是利用空间换取时间的快速查找算法
通过哈希函数将关键码映射到不同的位置,已达到快速查找的功能

假如关键码有40个,哈希表的位置有50个,通过哈希函数将这40个数以一定的
规律映射到表中,在你查找的时候直接调用函数就可以找到,但是,因为这个
哈希函数是自己定义的,就可能会存在将两个关键码映射到同一块地址上,就会
出现哈希冲突,要是关键码的个数大于哈希表的值,不仅会存在冲突问题吗,还
会存在溢出问题,则必须对位置取余操作。
//冲突原因:


1、处理冲突的方法是否恰当
2、哈希函数分配不够均匀
3、a负载因子太小(关键码/哈希表长度)a越大,则哈希表的剩余空间越小,
冲突概率越高
//解决冲突的方法:

                     一、开放定址法 
                      


1、线性探测:(步数为一步)j = (j+1)%num


当插入关键码时,如果发生冲突,可依次向后探测(每次走一步),直到找到
一个空的位置然后插入

当进行查找操作时,如果定位的地址没有值,则不存在,如果定位的位置有值,
则依次往后探测,直到遇到要查找的关键码,如果遇到了空地址还没有找到,
则不存在

//缺点:

//1、堆聚现象:
如果插入时,探测的次数比较多,那就带来一定的效率问题,而且假如每次插入
都需要探测,则冲突的可能性大大增强,产生堆聚现象(存在关键码全部连成
一片)


//2、删除出错:
删除时,本来我们只需要找到这个位置,然后清零操作,但是,由于可能会
存在冲突,影响后续的操作(这个位置后面还有与它相同的属性探测,
当置0时,后面就找不到了),所以我们只能将此位置设置为已删除的标记
//3:浪费空间
当为了减少冲突时,就会要求负载因子较小,则肯定会浪费空间



2、线性补偿探测(步数为n步)j =(j+n)%num(也可以理解为二次探测)
  当冲突时,再利用一个哈希函数探测一个位置

当插入关键码时,如果发生冲突,可依次向后探测(每次走n步)或者再利用
一个函数,直到找到一个空的位置然后插入

当进行查找操作时,如果定位的地址没有值,则不存在,如果定位的位置有值,
则依次往后探测,直到遇到要查找的关键码,如果遇到了空地址还没有找到,
则不存在

//缺点:
有效的解决了堆聚问题,但删除操作并不会有所改善


//高效的映射:
   1、有一个合适的哈希函数,比如说  质数    value% (一个质数)
 //当数据量小。哈希表大,造成资源浪费,当数据量多,表容量小,则资源
   不够?
   STL中:可以先选某个质数作为size,当数据量超过size,再次改一个
   更大的质数
 

 二、拉链 法
就是将所冲突的相同属性地址的关键码通过单链表的形式直接连在哈希表相对应
的位置上,哈希表中存放指向单链表第一个元素的指针,哈希表就是一个
指针数组。

这里写图片描述

//拉链法优点:
1、成功解决了线性探测带来的堆聚问题,平均查找长度变短
2、在进行删除时,相当于对单链表的任意位置的删除操作,并不需要标记,
3、由于节点都是动态开辟的,所以更适合利用在不知道表常长的情况下
4、节省空间,负载因子可大于等于1。
//缺点
当关键码规模较小时,开辟节点也会额外浪费空间,假如把开辟的空间用来
扩充哈希表的长度,就同样可以减少冲突。


//最广泛的哈希算法

MD4:基于32位操作系统的位运算来实现的
MD5:在MD4的基础上,每一步都增加了加法常数,优化了每轮循环左移的
位移量
SHA1

//哈希算法在信息安全方面的应用
①:抗冲突性(不能存在哈希冲突)
②:映射分布均匀,差分分布均匀
1、文件检测

常见的奇偶效验 和CRC效验   只进行数据的效验,并没有篡改能力

2、数字签名

通俗理解就是,对传输的数据进行特殊处理,编码,加密,在到达对方时,
再进行解密,反编码,
例如在http协议传输中的序列化,与反序列化


3、鉴权协议(接头信号)

你给对方发送一个随机信号,对方接受到随机信号后将接头信号与随机信号
进行哈希编码,再返还回去,就可以利用返回的信号判断接头信号是否正确
(安全性提高)

//哈希算法解决服务器负载均衡问题
问题描述:  例如手机朋友网有n个服务器,为了方便用户的访问会在服务器上
缓存数据,因此用户每次访问的时候最好能保持同一台服务器。已有的做法是
根据ServerIPIndex[QQNUM%n]得到请求的服务器,这种方法很方便将
用户分到不同的服务器上去。但是如果一台服务器死掉了,那么n就变为了
n-1,那么ServerIPIndex[QQNUM%n]与ServerIPIndex[QQNUM%
(n-1)]基本上都不一样了,所以大多数用户的请求都会转到其他服务器,
这样会发生大量访问错误。

 问:  如何改进或者换一种方法,使得:

(1)一台服务器死掉后,不会造成大面积的访问错误,

(2)原有的访问基本还是停留在同一台服务器上;

(3)尽量考虑负载均衡。


如果按照原有的取余映射,当服务器的数目减少一个时,再次映射会改变所有
的映射关系
这就会存在很多问题


哈希算法单调性:

当一些关键码映射到相对应的缓冲区后,如果再增加某一块缓冲区,哈希算法
应该可以保证以前的关键码可以可以映射到新的缓冲区,而不能映射到旧的
缓冲区的其他区域上
(要不你就不变,要不就映射到新的区域,决不能映射到其他旧的区域)


//一致性哈希算法

①、构建一个环形哈希表
②、将关键码通过哈希算法映射到不同的位置(尽量减少冲突)
③、再将服务器(通过IP计算)通过哈希映射到确定的位置
④、依次逆时针(或者顺时针)将所有的关键码绑定在与之相邻的服务器上

⑤、当进行删除一个服务器操作时,只需要把绑定当前服务器的key值在依次
连接到下一台服务器(按照开始的定制——逆时针)

⑥、当进行添加服务器操作时,只需要把要添加的服务器与上一个服务器
(逆时针)之间的key(逆时针)重新绑定到新的服务器即可。

这样操作只需要改变一小部分就可以实现要求。



  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值