哈希表(Hash table)(1)

  哈希表(Hash table)经常被用来做字典(dictionary),或称符号表(symbol-table)

直接存取表(Direct-access table):

? 直接存取表(Direct-access table)的基本思想是:如果key的范围为0~m-1而且所有key都不相同, 那么可以设计一个数组T[0..m-1],让T[k]存放key为k的元素, 否则为空(NIL)

? 显然, 所有操作都是O(1)的

? 问题:key的范围可能很大! 64位整数有18,446,744,073,709,551,616种可能, 而字符串的种类将会更多!

解决方案:哈希函数

? 严格均匀分布的哈希函数很难寻找, 但一般说来有三种方法在实际使用中效果不错

– 取余法:取h(k) = k mod m

– 乘积法:取h(k) = (A*k mod 2w ) rsh(w-r)

– 点积法:随机向量a和k的m进制向量做点积

? 实践中经常采用取余法

冲突(collision):

? 不同的key映射到同一个数, 称为冲突(collision),冲突的两个元素显然不可能放在

哈希表的同一个位置

? 通常有两种冲突解决方案(resolvingcollisions)

– 链方法(chaining):把key相同的串成链表

– 开放地址法(open addressing):自己的位置被占了, 就去占别人的

1)链地址法

? Key相同的元素形成一个链表

链地址法的查找效率

? 链地址法的时间效率取决于hash函数的分布. 我们假设每个k将等可能的被映射到任意一个slot,不管其他key被映射到什么地方

? 设n为key的数目, m为不同的slot数, 装载因子α= n/m,即每个slot平均的key数, 则

2)开放地址法:

? 开发地址法只使用表内的空间. 如果冲突产生, 计算出第二个可能的位置, 如果那里也有其他元素,再看第三个可能的位置… 即按一个探测序列查找

? 位置应该是key和探测的次数(probe number)的函数, 第i次探测位置为slot = h(k,i)

? 每个slot都应能被探测到, 因此每个k的探测序列h(k,0), h(k,1), h(k,2), …,h(k,m-1)

? 都应是{0,1,…,m-1}的排列

? 注意:开放地址法不容易删除元素

探测方法

? 线性探测:

? 虽然很简单, 但是容易形成元素堆积

? 二次哈希:组合两个哈希函数

? 一般效果会好很多,但应保证h 2 (k)和m互素, 比如取m为2的幂而让h 2 (k)只产生奇数

装载因子α<1时, 不成功查找的期望探测次数为1/ (1-α),证略。

在实际应用中,推荐使用链地址法

– first[i]表示哈希函数值为i的第一个数据下标

– key[i]和next[i]表示第i个数据的key和下一个

链地址法:

listNode* find(intk){
  int h = hash(k);
  listNode* p = first[h];
  while (p){ if(p->value == k) return p; p = p->next; }
  return 0;
}
void insert(int x){
  listNode* newNode = new listNode(x);
  int h = hash(key[x]);
  newNode->next = first[h];
  first[h] = newNode;
}
时间: 2024-10-05 00:08:31

哈希表(Hash table)(1)的相关文章

PHP关联数组与哈希表(hash table) 不指定

PHP中有一种数据类型非常重要,它就是关联数组,又称为哈希表(hash table),是一种非常好用的数据结构. 在程序中,我们可能会遇到需要消重的问题,举一个最简单的模型: 有一份用户名列表,存储了 10000 个用户名,没有重复项: 还有一份黑名单列表,存储了 2000 个用户名,格式与用户名列表相同: 现在需要从用户名列表中删除处在黑名单里的用户名,要求用尽量快的时间处理. 这个问题是一个小规模的处理量,如果实际一点,2 个表都可能很大,比如有 2 亿条记录. 我最开始想到的方法,就是做一

哈希表 hash table

散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构.也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度.这个映射函数叫做散列函数,存放记录的数组叫做散列表. 给定表M,存在函数f(key),对任意给定的关键字值key,代入函数后若能得到包含该关键字的记录在表中的地址,则称表M为哈希(Hash)表,函数f(key)为哈希(Hash) 函数. 首先问题规模确定,例如5台服务器怎么把数据散落在5台上面呢,就用到了hash算法

什么叫哈希表(Hash Table)

散列表(也叫哈希表),是根据关键码值直接进行访问的数据结构,也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度.这个映射函数叫做散列函数,存放记录的数组叫做散列表. - 数据结构中,有个时间算法复杂度O(n)的概念来衡量某种算法在时间效率上的优劣.哈希表的理想算法复杂度为O(1),也就是说利用哈希表查找某个值,系统所使用的时间在理想情况下为定值,这就是它的优势.那么哈希表是如何做到这一点的呢? - 我们定义一个很大的有序数组,想要得到位于该数组第n个位置的值,它的算法复杂度

[BS]散列表 哈希表 Hash table

<第五章> 散 列 散列表的实现常常叫做散列(hashing).散列是一种用于以常数平均时间执行插入.删除和查找的技术. 关于散列有一个很重要的概念:散列函数.散列函数是散列的关键处之一,散列函数又是基于映射机制的一种对应关系(一般是多对一的关系). 这章可以分为5个部分:一般想法,散列函数,分离链接法,开放定址法(可分为线性探测.平方探测.双散列).再散列.可扩散列. 本文只写到前四节.即:一般想法,散列函数,分离链接法,开放定址法(可分为线性探测.平方探测.双散列)() 第五章第一节:一般

哈希表Hash

大家都学过数据结构: 内存里面为了更好的管理对象,通常采用链表或者数据以及Hash表来存储数据. 数据存储 一下是数据存储到计算机的两种模式 线性的存储:数组---寻址方便,更新不好(连续的) 链式的存储: 链表----寻址不方便,更新方便.(不连续的) 为了提高检索的速度,我们可以采取Hash机制,key采取数据存储,方便寻址,其次我们可以利用链表方便更新数据的具体的值. 哈希表Hash,布布扣,bubuko.com

(四)Redis哈希表Hash操作

Hash的全部操作如下: hset key field value # 将哈希表key中的字段field的值设为value hget key field # 返回哈希表key中的字段field的值value hmset key field1 value1 field2 value2 ... # 将多个field-value对设置到哈希表key中 hmget key field1 field2 ... # 返回哈希表key中字段field1,field2,...的值 hgetall key # 返

哈希表Hash:概念与基本操作

什么是Hash Hash就像是一个桶排,那只不过是把各个元素的数值当做下标进行存储.其最常用的用途就是用来判重.但是,如何对字符串进行判重,不可能一个一个往前超,若n上万则显然不可行.我们可以选择进行Hash,将每一个字符串或者大数字进行一定的操作即可进行. 对大整数类型进行Hash 取模法 对于每一个大整数进行取模,即除以一个大质数(例如107,10007,1000007,1-奇数个0-7),这样就作为数组的下标进行存储了. 为什么要对一个大整数取模 emmmmmm......经众多数学家证明

哈希表——线性探测法、链地址法、查找成功、查找不成功的平均长度

一.哈希表 1.概念 哈希表(Hash Table)也叫散列表,是根据关键码值(Key Value)而直接进行访问的数据结构.它通过把关键码值映射到哈希表中的一个位置来访问记录,以加快查找的速度.这个映射函数就做散列函数,存放记录的数组叫做散列表. 2.散列存储的基本思路 以数据中每个元素的关键字K为自变量,通过散列函数H(k)计算出函数值,以该函数值作为一块连续存储空间的的单元地址,将该元素存储到函数值对应的单元中. 3.哈希表查找的时间复杂度 哈希表存储的是键值对,其查找的时间复杂度与元素数

浅谈算法和数据结构: 十一 哈希表

在前面的系列文章中,依次介绍了基于无序列表的顺序查找,基于有序数组的二分查找,平衡查找树,以及红黑树,下图是他们在平均以及最差情况下的时间复杂度: 可以看到在时间复杂度上,红黑树在平均情况下插入,查找以及删除上都达到了lgN的时间复杂度. 那么有没有查找效率更高的数据结构呢,答案就是本文接下来要介绍了散列表,也叫哈希表(Hash Table) 什么是哈希表 哈希表就是一种以 键-值(key-indexed) 存储数据的结构,我们只要输入待查找的值即key,即可查找到其对应的值. 哈希的思路很简单