DS:哈希表

高产真是高产
看的出来吧, 我一直在学习 !

1概述

哈希表(散列表)是一种数据结构, 它可以通过哈希函数将关键码映射到表中的某个位置, 从而使查找复杂度为O(1)

Address = Hash(key)

哈希函数通常是一个压缩映射函数, 必定存在多对一的情况, 也就是说一定会存在冲突

对于哈希函数的选择我们需要考虑两点: 分布均匀、尽量减少冲突;如何解决冲突。

实际编程中我们很少用到原理部分, 我们通常使用C++11中的unordered_set、unordered_map

2 哈希函数

2.1 除留余数法

很简单的一种,就是运用了模运算 hash(key) = key % p

关于p的选择:p选择不大于m(哈希表长度)接近m的质数, 若p选择2的i次幂, 则地址就是key的后i位二进制数字, 如key = 7(111), p = 2^2 = 4, add = 3(11)

2.2 数学分析法

分析所有出现的关键码, 选取某些分布均匀的位作为地址

2.3 平方取中法

将key平方后(扩大差别)再选取key^2的某几位(取决于m)

2.4 折叠法

将key按照哈希表地址空间位数划分成相等的几组叠加起来, 叠加方法有移位法和分界法

```eg: 239 385 878 41
    239   239
    385   583
    878   878
     41    14
   1543  1714(去掉最高位)
```

3 处理闭散列的方法

3.1 线性探测法(linear probing)

冲突的话, 就从冲突的地方向后移找地址, 容易聚集

Hi = (Hi-1 + 1) % m

3.2 二次探测法(quadratic probing)

Hi = (H0 - i^2) % m Hi = (H0 + i^2) % m;

解决了单方向堆积, 减轻了堆积

但是可能有空间也找不到,因为 H0, H0 + 1, H0 - 1, H0 + 4, H0 - 4

所以散列表的大小必须是4k + 3的质数, 避免有些地方探测不到

3.3 双散列法

就是用两个散列函数, 一个平常计算用,另一个冲突了再用

3.4 再散列法

如果冲突了是元素太多了,我们重新扩充散列表,重新散列(好累)

4 处理开散列的方法

就是每个桶内放的是一个链表, 冲突了就往后接就行了

5 总结

哈希表适合用于查找较多、关键字比较计算量比较大, 空间换时间, 与问题的规模n无关, 不适合顺序查找关键字

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值