Zabbix原理和5.0的部署

三层链路聚合是如何工作的?

  返回  

排序与查找--散列和冲突解决方案(python)

2021/8/20 23:58:17 浏览:

文章目录

    • 1.散列
    • 2.完美散列函数
    • 3.散列函数设计
      • 3.1折叠法
      • 3.2平方取中法
      • 3.3非数字项
    • 4.冲突解决方案
      • 4.1线性探测
      • 4.2数据项链

1.散列

概念:散列表(Hashing)又叫哈希表。查找算法复杂度为O(1),常数级别。

查找快的原因:因为事先知道数据项在数据集的什么位置,直接到那个位置去看看数据是否存在即可。

散列表(哈希表)

  • 散列表是一种数据集。
  • 散列表中的每一个存储位置,称为( slot),可以用来保存数据项,每个槽有一个唯一的名称(槽号)

例如:如下图所示,一个包含11个槽的散列表,槽的名称分别为0~10。在插入数据项之前,每个槽的值都是None,表示空槽。
在这里插入图片描述
散列函数(hash function):数据项关于槽号的函数,比如y=2x,一样,数据项=2×槽号,数据项为2时,槽号为1。

有一种常用的散列方法是"求余数",将数据项除以散列表的大小,得到的余数作为槽号

例如:将数据项:94,26,93,17,77,31保存到散列表中,请设计一个散列函数,数据项为参数,返回整数0~10,作为槽的名称。

:h(item)=item%11,item为数据项,item%11为槽号

在这里插入图片描述
要查找数据项是否在表中,只需要用散列函数根据数据项计算出槽号,然后查找槽号里有没有数据项即可。

可能有两个数据项计算出来放在同一个槽中,这叫做冲突,冲突怎么解决呢?一会儿再看。

2.完美散列函数

概念:给定一组数据项,如果一个散列函数能把每个数据项映射到不同的槽中,那么这个散列函数就可以称为"完美散列函数

获得完美散列函数的一种方法:扩大散列表容量,大到所有可能出现的数据项都能占据不同的槽。

好的散列函数的特性

  • 冲突最少(近似完美)
  • 计算难度低(额外开销少)
  • 充分分散数据项(节约空间)

python自带的散列函数库:hashlib:
在这里插入图片描述
update()可对任意长数据部分计算
在这里插入图片描述

3.散列函数设计

3.1折叠法

基本步骤
例如:

对电话号码62767255
将数据项按照位数分为若干段,
可以两位两位分为4段(62、76、72、55)
再将几段数字相加,
得到散列值相加(62+76+72+55=265)
最后对散列表大小求余,
散列表包括11个槽,那么就是265%11=1所以
h(62767255)=1

隔数反转:(微调)
(62,76,72,56)隔数反转为(62,67,72, 65

3.2平方取中法

例如

首先将数据项做平方运算,
对44进行散列首先44*44=1936
然后取平方数的中间两位,
然后取中间的93
再对散列表的大小求余
对散列表大小11求余,93%11=5

3.3非数字项

如下图,ord函数把字符串中每个字符转为ASCII码(ord(“c”=99)),再将整数累加,对散列表大小求余。
在这里插入图片描述
代码:
在这里插入图片描述
变位词:abc 和 bac

如何防止所有变位词返回同一个槽
如下图,字符串所在位置乘以ord值再相加求余。
在这里插入图片描述

4.冲突解决方案

冲突两个数据项被散列映射到一个槽

4.1线性探测

解决方法:寻找空槽(开放定址),逐个槽寻找(线性探测)

聚集:线性探测法的一个缺点是有聚集 clustering)的趋势
即如果同一个槽冲突的数据项较多的话,这些数据项就会在槽附近聚集起来。从而连锁式影响其它数据项的插入。

解决方法:再散列,即不是逐个槽寻找,可以空3个槽寻找。叫做跳跃式探测。

跳跃式探测的再散列通式是∶rehash(pos)=(pos+skip)% sizeoftable

skip取值不能被散列表大小整除,否则会产生周期,让很多空槽永远无法被探测到。(可把散列表大小设为素数

4.2数据项链

在这里插入图片描述

联系我们

如果您对我们的服务有兴趣,请及时和我们联系!

服务热线:18288888888
座机:18288888888
传真:
邮箱:888888@qq.com
地址:郑州市文化路红专路93号