相关概念
散列表 hashtable 是一种实现字典操作的有效数据结构.
在散列表中,不是直接把关键字作为数组的下标,而是根据关键字计算出相应的下标. 散列函数 hashfunction'h'
除法散列法

通过取k除以m的余数,将关键k映射到m个slot中的某一个上.即散列函数为:h(k)=kmodm
比如:散列表的大小m=12,关键字k=100,则h(k)=100mod12=4,放到slot4中.
由于只需做一次除法,所以除法散列法速度非常快.
当选择除法散列法的时候,要避免选择m的某些值。例如,m不应为2的幂.因为如果m=2的p次幂.
则h(k)=就是k的p个最低位数字.
一个不太接近2的整数次幂的素数,常常是m的一个较好的选择.例如,假定我们要分配一个张散列表用链接
法解决冲突,表中大约要存放n=2000个字符串,其中每个字符串有8位.如果我们不介意一次不成功的查找
需要平均检查3个元素,这样分配散列表的大小为701.因为701是一个接近2000/3但是又不接近2的任何次幂的素数. 乘法散列法
乘法散列法包含两个步骤:第一:用关键字k乘上常数A(0<A<1),并提取kA的小数部分.
第二步,用m乘以这个值,再向下取整:h(k)=int(m(KAmod1))
乘法散列的一个优点是对m的选择不是特别关键,一般选m为2个某个次幂.m=2的p次幂. 开放寻址 openaddressing
开放寻址openaddressing中,所有元素都存放在散列表里.
每个表项或包含动态集合的一个元素,或包含NIL.当查找某个元素的时候,要系统的检查所有表项,直到找到所需的元素或最终找不到该元素. 有三种技术常用来计算开放寻址法中的probesequence探查序列:线性探查,二次探查和双重探查.
线性探查 linearprobing: 散列函数:h(k,i)=(h'(k)+i)modm
二次探查 quadraticprobing:散列函数:h(k,i)=(h'(k)+c1i+c2i*i)modm
双重散列 doublehashing:是用于开放寻址的最好方法,因为它所产生的排列具有随机选择排列的许多特性. 散列函数:h(k,i)=(h1(k)+i*h2(k)modm
为了能查找整个散列表,值h2(k)必须要与表的大小m互素.一种简单的方法确保这个条件成立,就是取m为2的幂.
并设计一个总产生奇数的h2.另一个方法是:取m为素数,并设计一个总是返回较m小的正整数的函数h2.
例如: h1(k) = k mod m, h2(k) = 1 + (k mod m') , 其中 m' 略小于 m, 比如 m' = m-1
Python program
Perfect hashing

Using perfect hashing to store K=[10,22,37,40,52,60,70,72,75]
注: 下图中所示元素 40 的位置是不对的. 最后 T 为:
                 T = [[1,0,0,10], 'NIL', [9,10,18,'NIL','NIL','NIL',60,72,'NIL','NIL',75,'NIL'], \
'NIL', 'NIL', [1,0,0,70], 'NIL', [16,23,88,'NIL','NIL','NIL','NIL','NIL','NIL',\
40,52,22,'NIL','NIL','NIL','NIL',32,'NIL'], 'NIL']

def produce_t(T0):
import copy
T = copy.deepcopy(T0)
for i in range(len(T)):
if T[i] != 'NIL':
T[i] = T[i] + ['NIL' for x in range(T[i][0])]
return T def h(k, m=9, a=3, b=42, p=101,): # h function
# a = 3
# b = 42
# p = 101
# m = 9
return ((a*k + b) % p)%m def perfect_hash(T, k):
h1 = h(k)
h2 = h(k,T[h1][0],T[h1][1],T[h1][2])
T[h1][h2+3] = k
print(' h1 and h2 : ', h1,h2) if __name__ == '__main__':
#m = 9 K = [10, 22, 37, 40, 52, 60, 70, 72, 75]
# T = [[1,0,0,10], 'NIL', [9,10,18,'NIL','NIL','NIL',60,72,'NIL','NIL',75,'NIL'], \
# 'NIL', 'NIL', [1,0,0,70], 'NIL', [16,23,88,'NIL','NIL','NIL','NIL','NIL','NIL',\
# 40,52,22,'NIL','NIL','NIL','NIL',32,'NIL'], 'NIL'] T0 = [[1, 0, 0], 'NIL', [9, 10, 18], 'NIL', 'NIL', [1, 0, 0], 'NIL', [16, 23, 88], 'NIL'] print('Initializing T')
T = produce_t(T0)
#print(T0)
print('T: ', T) print('example of the element 75')
print('h result of 75')
print(h(75))
print('Hashing of 75')
perfect_hash(T, 75)
print('T: ', T) print('Hashing of list K')
for i in K:
print('Hashing of : ', i)
perfect_hash(T,i)
print('T: ', T) 结果打印:
Initializing T
T: [[1, 0, 0, 'NIL'], 'NIL', [9, 10, 18, 'NIL', 'NIL', 'NIL', 'NIL', 'NIL', 'NIL', 'NIL', 'NIL', 'NIL'],
'NIL', 'NIL', [1, 0, 0, 'NIL'], 'NIL',
[16, 23, 88, 'NIL', 'NIL', 'NIL', 'NIL', 'NIL', 'NIL', 'NIL', 'NIL', 'NIL', 'NIL', 'NIL', 'NIL', 'NIL', 'NIL', 'NIL', 'NIL'], 'NIL']
example of the element 75
h result of 75
2
Hashing of 75
h1 and h2 : 2 7
T: [[1, 0, 0, 'NIL'], 'NIL', [9, 10, 18, 'NIL', 'NIL', 'NIL', 'NIL', 'NIL', 'NIL', 'NIL', 75, 'NIL'],
'NIL', 'NIL', [1, 0, 0, 'NIL'], 'NIL',
[16, 23, 88, 'NIL', 'NIL', 'NIL', 'NIL', 'NIL', 'NIL', 'NIL', 'NIL', 'NIL', 'NIL', 'NIL', 'NIL', 'NIL', 'NIL', 'NIL', 'NIL'], 'NIL']
Hashing of list K
Hashing of : 10
h1 and h2 : 0 0
Hashing of : 22
h1 and h2 : 7 9
Hashing of : 37
h1 and h2 : 7 14
Hashing of : 40
h1 and h2 : 7 3
Hashing of : 52
h1 and h2 : 7 8
Hashing of : 60
h1 and h2 : 2 3
Hashing of : 70
h1 and h2 : 5 0
Hashing of : 72
h1 and h2 : 2 4
Hashing of : 75
h1 and h2 : 2 7
T: [[1, 0, 0, 10], 'NIL', [9, 10, 18, 'NIL', 'NIL', 'NIL', 60, 72, 'NIL', 'NIL', 75, 'NIL'],
'NIL', 'NIL', [1, 0, 0, 70], 'NIL',
[16, 23, 88, 'NIL', 'NIL', 'NIL', 40, 'NIL', 'NIL', 'NIL', 'NIL', 52, 22, 'NIL', 'NIL', 'NIL', 'NIL', 37, 'NIL'], 'NIL']

Reference 

    1. Introduction to algorithms

Algorithms - Data Structure - Perfect Hashing - 完全散列的更多相关文章

  1. 【Java集合学习】HashMap源码之“拉链法”散列冲突的解决

    1.HashMap的概念 HashMap 是一个散列表,它存储的内容是键值对(key-value)映射. HashMap 继承于AbstractMap,实现了Map.Cloneable.java.io ...

  2. Hashing散列注意事项

    Hashing散列注意事项 Numba支持内置功能hash(),只需__hash__()在提供的参数上调用成员函数即可 .这使得添加对新类型的哈希支持变得微不足道,这是因为扩展APIoverload_ ...

  3. PAT A1145 Hashing - Average Search Time (25 分)——hash 散列的平方探查法

    The task of this problem is simple: insert a sequence of distinct positive integers into a hash tabl ...

  4. [Algorithms] Tree Data Structure in JavaScript

    In a tree, nodes have a single parent node and may have many children nodes. They never have more th ...

  5. [No0000132]正确使用密码加盐散列[译]

    如果你是一个 web 开发工程师,可能你已经建立了一个用户账户系统.一个用户账户系统最重要的部分是如何保护密码.用户账户数据库经常被黑,如果你的网站曾经被攻击过,你绝对必须做点什么来保护你的用户的密码 ...

  6. 散列(Hash)表入门

    一.概述 以 Key-Value 的形式进行数据存取的映射(map)结构 简单理解:用最基本的向量(数组)作为底层物理存储结构,通过适当的散列函数在词条的关键码与向量单元的秩(下标)之间建立映射关系 ...

  7. 【数据结构与算法Python版学习笔记】查找与排序——散列、散列函数、区块链

    散列 Hasing 前言 如果数据项之间是按照大小排好序的话,就可以利用二分查找来降低算法复杂度. 现在我们进一步来构造一个新的数据结构, 能使得查找算法的复杂度降到O(1), 这种概念称为" ...

  8. Java 消息摘要 散列 MD5 SHA

    package xxx.common.util; import java.math.BigInteger; import java.security.MessageDigest; import jav ...

  9. 个人理解c#对称加密 非对称加密 散列算法的应用场景

    c#类库默认实现了一系列加密算法在System.Security.Cryptography; 命名空间下 对称加密 通过同一密匙进行加密和解密.往往应用在内部数据传输情况下.比如公司a程序 和B程序 ...

随机推荐

  1. Clustered和Nonclustered Indexes 各自得特点和区别及长短处

    1 簇索引 簇索引对表的物理数据页中的数据按列进行排序然后再重新存储到磁盘上即簇索 引与数据是混为一体的它的叶节点中存储的是实际的数据由于簇索引对表中的数据一 一进行了排序因此用簇索引查找数据很快但由 ...

  2. Android MVP 十分钟入门!

    前言 在日常开发APP 的过程中,随着业务的扩展,规模的变化.我们的代码规模也会逐渐变得庞大,每一个类里的代码也会逐渐增多.尤其是Activity和Fragment ,由于Context 的存在,基本 ...

  3. Vagrant (二) - 日常操作

    立即上手 上一节中,我们介绍了怎样安装 Vagrant,安装本身并不困难.本章节中我们首先要快速上手,以便获得一个直观的概念: 建立一个工作目录 打开命令行工具,终端工具,或者iTerm2等,建立一个 ...

  4. 在服务器上发布第一个.net项目

    作为一名前端开发者,对后端一窍不通可是不行的.公司后端所用的恰好是.net技术,日常开发常见MVC架构,然而还是对MVC不甚了解,前端开发也多有掣肘.本人很想摸索清楚如何构建一个asp.net的项目, ...

  5. RMI原理揭秘之远程对象

    讨论开始之前,我们先看看网上的一个例子,这个例子我腾抄了一分,没有用链接的方式,只是为了让大家看得方便,如有侵权,我立马***. 定义远程接口: 1 2 3 4 5 6 package com.guo ...

  6. HDU 1233 最小生成树模板题,练练模板

    还是畅通工程 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Sub ...

  7. 数据源管理 | 基于DataX组件,同步数据和源码分析

    本文源码:GitHub·点这里 || GitEE·点这里 一.DataX工具简介 1.设计理念 DataX是一个异构数据源离线同步工具,致力于实现包括关系型数据库(MySQL.Oracle等).HDF ...

  8. Flutter 1.17版本重磅发布

    Flutter 1.17 是2020年的第一个稳定版本,此版本包括iOS平台Metal支持(性能更快),新的Material组件,新的Network跟踪工具等等! 对所有人来说,今年是充满挑战的一年. ...

  9. 龟兔赛跑算法 floyed判环算法

    今天写线段树写到要用到这个算法的题目,简单的学习一下. https://blog.csdn.net/javaisnotgood/article/details/89243876 https://blo ...

  10. 前端【JS】,深拷贝与浅拷贝的区别及详解!

    我是前端小白一枚,为了巩固知识和增强记忆,开始整理相关的知识,方便以后复习和面试的时候看看.OK,让我们进入正题~ 先说说浅拷贝和深拷贝的理解吧,个人是这样理解的:两个对象A.B, A有数据B为空,B ...