快速理解哈希(Hash)表的运作原理

哈希表是什么

哈希表(hash table)又叫散列表。

和二叉树、链表这一类一样。它是一种数据结构,设计出来用于存放数据。

百科解释:

散列表(Hash table,也叫哈希表),是根据键(Key)而直接访问在内存存储位置的数据结构。也就是说,它通过计算一个关于键值的函数,将所需查询的数据映射到表中一个位置来访问记录,这加快了查找速度。这个映射函数称做散列函数,存放记录的数组称做散列表

  

需要的基础知识

指针和数组

链表

模运算

    

哈希表的构建方法

  1. 创建一个固定大小的数组(哈希表),其中每个位置都有一个关联值为null或空链表
  2. 对需要存储的数据应用哈希函数(核心)---- 使用取模运算符将数据转换为数组的下标(即关键字 x -- f(x)(哈希函数)--> 下标)
  3. 将数据存储在该下标位置处(便于查找)。

如下:

数组

指针

指针

指针

指针

指针

下标

0

1

2

3

4

5

6

7

8

...

    

哈希函数是根据关键字设计的,有很多种函数,主要的原理就是根据数组的大小求模运算。

(关键字) % (数组大小)

例如:20048157 % 17 (结果在0-16)

数组的大小一般设计为质数 -- ?--> 保证均匀分布(即:将输入数据随机(均匀)散布到哈希表的各个位置,避免出现过多冲突)。

   

遇到冲突怎么办

1、链表式解决(Separate Chaining)

写结构体的时候加入next指针(和链表一样)

数据 Next->数据 Next

遇到冲突的时候,把数据写到next的位置.

例如:

数据关键字

15 22 24 16

数组大小

7

哈希函数

下标 = 关键字 mod 7

 ↓↓结果

下标

数据

0

1

15

->

22

2

16

3

24

4

5

6

产生冲突时,往后面放指针(15->22->...)


  

2、开放地址(Open Addressing)

不用next指针,把其他下标的位置都对外开放。

    

开放地址的方法:

a. 线性探测法

如果遇到冲突,就往下一个地址寻找空位。

如果遇到冲突,新位置=原始位置+ i(i是冲突的次数)

     

例如:

数据关键字

28 4 12

数组大小

13

哈希函数

下标=关键字 mod 13

↓↓结果

数组

12

15

2

28

4

38

下标

0

1

2

3

4

5

6

7

8

9

10

11

12

缺点:容易产生“二次聚集”---- 不同基地址的元素争夺同一个单元的现象叫作“二次聚集”。(也即扎堆)


b. 平方探测法(二次方探测)

如果遇到冲突,就往(原始位置 + i方 )的位置

寻找空位(i 代表冲突的次数)

如果遇到冲突,新位置 = 原始位置 + i方

   

例如:

数据关键字

15 2 28 19 10

数组大小

13

哈希函数

下标 = 关键字 mod 13

↓↓结果

数组

15

2

19

28

10

下标

0

1

2

3

4

5

6

7

8

9

10

11

12


c.双哈希

要设置第二个哈希的函数,例如: hash2(key)=R-(key mod R)

R要取比数组尺寸小的质数。

例如R=7: hash2(关键字)= 7- (关键字% 7 )

也就是说,二次哈希的结果在1-7之间,不会等于0;

如果遇到冲突,新位置=原始位置+ i . hash 2(关键字)

例如:

数据关键字

15 2 18 28

数组大小

13

哈希函数

下标=关键字 mod 13

哈希函数2

7-(关键字 mod 7)

如果遇到冲突,新位置=原始位置+i.hash 2(关键字)

↓↓结果

数组

15

18

2

28

下标

0

1

2

3

4

5

6

7

8

9

10

11

12



哈希表满了怎办?

再次哈希(Rehashing)

当哈希表数据存储量超过70%,那么就自动新建一个新的哈希表

新表的尺寸是旧表的2倍以上,选择-一个质数

把之前的数据再次通过哈希计算搬到新表里

     

如果往旧表里再插入-一个数据,那么旧表的存储量将会超过70%

旧表:

6

15

2

24

13

0

1

2

3

4

5

6

旧表:下标=关键字mod 7

新表:下标=关键字mod 17

新表:

2

24

6

13

15

0

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

     

为什么设计哈希表

因为哈希表查找的性能快,它比搜索叉树的速度还快。

搜索二叉树的查找速度是0(log2 N),而哈希表发挥稳定的话

可以达到0(1)。

    

哈希表的缺点

表越满,性能越差

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值