前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >PHP数据结构(十五) ——哈希表​

PHP数据结构(十五) ——哈希表​

作者头像
用户1327360
发布2018-03-07 10:53:28
1.4K0
发布2018-03-07 10:53:28
举报
文章被收录于专栏:决胜机器学习决胜机器学习

PHP数据结构(十五)——哈希表

(原创内容,转载请注明来源,谢谢)

一、概述

查找的效率与查找的次数有关,查找的次数越少速度越快。因此,希望能够一次查找出结果,此时键值一一对应,称满足这条件的f(k)为哈希函数。

1、定义

1)冲突

不同的关键字通过哈希函数,得到同一个地址,称为冲突。具有相同函数值的关键字称为同义词。

2)哈希表

根据设定的哈希函数H(key)和处理冲突的方法,将一组关键字映像到一个有限连续的地址集上,以关键字的“像”作为记录的位置,此表称为哈希表,映像过程称为哈希造表或散列,所得存储位置称哈希地址或散列地址。

2、性质

哈希函数是一个映像,设定灵活,任何关键字由此所得的哈希值落在表长允许范围内。

二、构造哈希表

对于关键字集合中的任意一个关键字,经哈希函数映像到地址集合中的任一地址的概率是相等的,称为均匀的哈希表。

1、直接定址法

取关键字或某个线性函数作为哈希地址,即H(key)=key,或(key)=a*key+b(a、b都是常数)。

该方法地址集合和关键字的大小一样,不会有冲突,但是实际上很少用到。

2、数字分析法

此方法适用于能够预先估计到全部的结果。假设关键字是以R为基的数(例如R=10的十进制),且可以知道哈希表的所有值,则可以用关键字的一部分组成哈希地址。

例如,10000-10099,可以用key0-99来表示。

3、平方取中法

取关键字平方和的中间几位作为地址。此方法类似数字分析法,将关键字进行平方的目的是拉大两个关键值之间的差距。该方法较为常用。因为平方之后的中间几位和这个数的每个数字都有关,具体位数由表长决定。

4、折叠法

将关键字分割成几部分,这几部分叠加和(舍去进位)作为哈希地址。当关键字很长,且分布均匀时,可以采用此方法。

5、除留余数法

取关键字被某个不大于哈希表表长m的数p除后所得余数为哈希地址。

即H(key)=keyMOD p(p<=m),该方法比较简单,而且可以结合折叠、平方取中等方式。但是要注意,选的数不能太小,也最好不要有很多因数,否则有可能取出来的余数相同的太多。最好选择20以上的质数来取余。

6、随机数法

选择一个随机数,取关键字的随机函数值为它的哈希地址,即H(key)=random(key)。通常,当关键字长度不等时采用此法构造哈希函数比较恰当。

三、构造过程需要考虑的因素

1、计算哈希函数所需的时间,包括硬件指令的因素。

2、关键字的长度。

3、哈希表的大小。

4、关键字的分布情况。

5、记录查找的频率。

四、冲突处理方法

使用哈希函数,很有可能会出现冲突,即多个数经过哈希函数得到同一个结果。此时,就需要冲突处理方法,来使得发生冲突的关键字能够得到一个单独的映射结果。冲突处理方法,用符号Hi表示。

1、开放定址法

发生冲突的哈希值,加上一个数,在取余,可以得到另一个结果,可以作为冲突解决的方式,即:

Hi= ( H(key) + di ) MOD m (i=1,2…k)(k<=m-1)。其中,H(key)为哈希函数,m为哈希表表长,di为增量序列,可以有以下三种取法:

1)线性探测再散列,di=1,2,3…m-1

2)二次探测再散列,di=1,-1,4,-4,9,-9…(m/2)2

3)伪随机数序列

以上三种结果各有好坏。

1)使用线性探测再散列,可以理解为取点i作为哈希值,如果发生冲突,就取i+1,如果还冲突,就取i+2。这样可以保证,只要哈希表还有空间,就一定能够取得哈希值。但是,这样速度会比较慢,特别是比较密集的区间,可以要连续做好几次的冲突处理才可以得到一个结果。

2)使用二次探测再散列,速度将比较快,因为其是采用平方的方式,而不是逐一递增,因此在经过i次的查找,其查找的范围达到i2,这样有效跳出一个大范围的区间。但是,因为这个方式不是逐一取结果,因此有可能最终没有找到能使用的哈希值。

3)伪随机数是随机的数,则结果不稳定,有可能特别快,也有可能特别慢。

2、再哈希法

Hi=RH(key)。即发生冲突时,换一种冲突处理方式,来解决冲突。

3、链地址法

该方法取得的哈希值键值不是一一对应的,而是一个哈希值指向一个存储空间,该空间是一个线性链表,由所有哈希结果一致的键组成。该方式可以保证哈希的结果足够快,不需要进行再哈希或者开放地址计算,也能保证每一个键一定可以有哈希值。但是,查找的时候相对速度较慢,因为需要在链表里面逐一判断结果。

4、建立公共溢出区

该方式为补救措施,即建立一个公共的区域,所有无法取得哈希的结果都放在此区域。该方式获取结果效率会比较低,但是作为补救措施,可以保证数据不丢失。

——written by linhxx 2017.07.15

相关阅读:

PHP数据结构(十四) ——键树(双链树)

PHP数据结构(十三) ——动态查找表(二叉排序树)

PHP数据结构(十二) ——静态查找表​

PHP数据结构(十一) ——图的连通性问题与最小生成树算法(2)

PHP数据结构(十一) ——图的连通性问题与最小生成树算法(1)

PHP数据结构(十) ——有向无环图与拓扑算法

PHP数据结构(九) ——图的定义、存储与两种方式遍历

PHP数据结构(八) ——赫夫曼树实现字符串编解码(实践2)

PHP数据结构(八) ——赫夫曼树实现字符串编解码(实践1)

PHP数据结构(八) ——赫夫曼树实现字符串编解码(理论)

PHP数据结构(七) ——串与实现KMP算法

PHP数据结构(六) ——树与二叉树之概念及存储结构

PHP数据结构(六) ——数组的相乘、广义表

PHP数据结构(五) ——数组的压缩与转置

PHP数据结构(四) ——队列

PHP数据结构(三)——运用栈实现括号匹配

PHP数据结构(二)——链式结构线性表

PHP数据结构(一)——顺序结构线性表

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-07-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 决胜机器学习 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 相关阅读:
    • PHP数据结构(十四) ——键树(双链树)
      • PHP数据结构(十三) ——动态查找表(二叉排序树)
        • PHP数据结构(十二) ——静态查找表​
          • PHP数据结构(十一) ——图的连通性问题与最小生成树算法(2)
            • PHP数据结构(十一) ——图的连通性问题与最小生成树算法(1)
              • PHP数据结构(十) ——有向无环图与拓扑算法
                • PHP数据结构(九) ——图的定义、存储与两种方式遍历
                  • PHP数据结构(八) ——赫夫曼树实现字符串编解码(实践2)
                    • PHP数据结构(八) ——赫夫曼树实现字符串编解码(实践1)
                      • PHP数据结构(八) ——赫夫曼树实现字符串编解码(理论)
                        • PHP数据结构(七) ——串与实现KMP算法
                          • PHP数据结构(六) ——树与二叉树之概念及存储结构
                            • PHP数据结构(六) ——数组的相乘、广义表
                              • PHP数据结构(五) ——数组的压缩与转置
                                • PHP数据结构(四) ——队列
                                  • PHP数据结构(三)——运用栈实现括号匹配
                                    • PHP数据结构(二)——链式结构线性表
                                      • PHP数据结构(一)——顺序结构线性表
                                      领券
                                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档