10/25 哈希表

本文深入探讨哈希表的工作原理,包括哈希函数的性质、静态哈希的不足及解决方案,如动态调整桶数量的可扩展哈希,以及处理哈希冲突的方法,如拉链法、线性探测法等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

部分内容参考文档:

  1. https://blog.youkuaiyun.com/caianye/article/details/5839917
  2. https://www.cnblogs.com/penghuwan/p/8458269.html#_label0
    为什么要使用哈希表

Hashing

Hash函数的性质

一致性:具有相同关键字的值被赋给同一个桶中。

随机性:每个桶将会有相同数据的记录,而不考虑文件中关键字的真实分布。

最坏性:把所有的关键字映射到同一个桶中,使得访问时间和文件中关键字的数量成正比。

Static Hashing:
在这里插入图片描述
如果没有空间剩余,将会分配overflow buckets, 用链表把它们连接起来。(长的链表降低了性能)

Deficiency:

一:如果初始桶的数量很少,随着文件的增长,性能将会因为太多的overflow buckets下降。

二:如果分配期望增长的空间,那么大量的空间在开始的时候都浪费了。

三:如果数据库比较小,空间再次浪费了。

One Solution: 周期的用新的Hash函数重新组织文件。

缺点是:昂贵,打乱了正常的操作。

Better solution: 动态的改变桶的数目。

Extendible Hashing

既然桶装满了,为何不用双倍的桶来组织文件?

一:只需要分裂溢出的桶。(但是读写所有的文件是很昂贵的)

Idea:使用指向桶的指针目录,通过双倍指针目录来双倍桶。因为指针目录比文件小,所以双倍指针目录会更划算。
在这里插入图片描述

symbol table(潜在无穷的集合)
碰撞是一定会有的,函数不可能设计成一对一的。所以问题转化为如何处理碰撞。
collisions(冲突)
The birthday problem

删除:
计算哈希地址

简单的关键字取得策略:
①h(k) = k mod m
e.g. m = 12, k=100 ,h(k)=4
②二进制表示后几位
③m取素数能表示比较均匀的分布

关于同义词(k1,k2)
k1≠k2
h(k1)=h(k2)

怎么设计哈希函数:
在这里插入图片描述
如果是字符串,则设计其转化为十进制数。
在这里插入图片描述

task:

①怎么判断哪个哈希函数分布值更均匀:
②怎么解决冲突:
  1. 拉链法
  2. 线性探测法
  3. 再哈希法
  • instread of a hash table, we use a table of linked list
  • keep a linked list of keys that hash to the same value
    在这里插入图片描述
    relocation scheme
    ①Linear Probing
  • f(i)=i

为什么链表链在前面更简单?
设计表的结构,怎么构造表?

再哈希
当插入的数大于预估

double hashing example

http://www.cplusplus.com/forum/general/88539/

比较好的哈希函数是time33算法。PHP的数组就是把这个作为哈希函数。

核心的算法就是如下:

unsigned long hash(const char* key){
    unsigned long hash=0;
    for(int i=0;i<strlen(key);i++){
        hash = hash*33+str[i];
    }  
    return hash;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值