算法入门——散列

Posted 似梦半醒

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法入门——散列相关的知识,希望对你有一定的参考价值。

散列hash

一、散列的定义

  定义:散列就是将元素带入一个函数进行计算从而得到一个整数,要求这个计算结果可以尽可能唯一的标识这个元素,而这个函数就是散列函数H,如果元素转换前是key,那么转换后就是整数H(key)

  上面的定义可能很抽象,我尝试通俗解释一下,就是说我有若干个元素,这个元素可以是任意类型的,但是所有元素应该是同一种类型,现在要求把这些元素进行分类,而分类的规则就是上文中的散列函数,要求就是分类后每类都只代表唯一的元素。比如说我有一筐苹果,现在需要将这些苹果进行散列,我可以按“取苹果的果径”进行散列,只要对于果径的测量足够精确,是可以做到每个直径对应一个苹果,这就完成了散列操作。

 

二、整数散列

  了解定义以后请思考一种特殊情况,给出的key是整数,就是说要对一组整数进行散列,常见的散列方法有直接定址法、平方取中法、除留余数法等;

  (一)直接定址法:H(key)=key,就是按照数字本身进行散列,或者用一个线性函数H(key)=a*key+b;

  (二)平方取中法:key的平方的中间若干位作为hash值

  (三)除留取余法:把key除以某个数mod得到余数作为hash值,H(key)=key%mod

   通过除留取余,可以将很大的数转换为一个不超过mod的数,这样就可以将这个数放在一个长度大于mod的数组中(表),所以mod经常取素数,这样可以保证H(key)的最大限度的不同

以下的散列操作都在数组中存放数据

    1、冲突:如果H(key1)和H(key2)的值相同,就会发生冲突,所以要避免冲突

    2、冲突避免:

     (1)线性探查法:如果当前H(key)产生冲突那么就查找H(key)+1的位置是否冲突,重复数次+1操作,一定可以找到一个不冲突的位置(空间足够)

     (2)平方探查法:如果出现冲突就顺序查找H(key)+1^2、H(key)-1^2、H(key)+2^2、H(key)-2^2……如果在此过程中出现H(key)+k^2超出表长,就拿它对表长取模;如果                      H(key)-k^2<0;超出表首,就让hash=((H(key)-k^2)%size+size)%size,就是让这个hash不断对加表长直到非负;实际操作可以不做减法操作

     (3)链地址法:把所有hash相同的key连接成一个单链表,冲突元素组成链表,查询时可以遍历链表

 

三、字符串散列(408不要求)

  可将A-Z对应为0-25,a-z对应为26-51

  这里只考虑A-Z这种情况(字符串中只有大写),小写同理

  让A-Z对应0-25,这样就让字符串构成了一个26进制数,每个字符就是一个数,然后将这个26进制数转换成10进制数,每个字符串就有一个对应的十进制数作为hash

以上是关于算法入门——散列的主要内容,如果未能解决你的问题,请参考以下文章

搜索算法入门详解

JS逆向你必须懂的常用加密算法

NumPy入门讲座:实战演练

《算法竞赛入门经典(第2版)》pdf下载在线阅读,求百度网盘云资源

Java入门算法(树篇)

Java入门算法(树篇)