您现在的位置是:首页 >学无止境 >快速理解哈希(Hash)表的运作原理网站首页学无止境

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

凌慕 2023-06-25 15:48:51
简介快速理解哈希(Hash)表的运作原理

哈希表是什么

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

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

需要哪些基础知识

指针和数组

链表

模运算

哈希表的构建方法:

1.创建一个固定大小的数组

2.对需要进行存储的数据应用哈希函数,将数据转换为数组的索引位置

3.将数据存储在该索引位置处

如下:

数组

指针

指针

指针

指针

指针

下标

0

1

2

3

4

5

6

7

8

...

关键字:x -> f(x)(哈希函数)->下标

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

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

例如: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

(说明:28%13=2,由于下标2占位,往后寻找空位放入即最终找到下标4这个空位;4、12同理)


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

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

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

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

例如:

数据关键字

2 28 19 10

数组大小

13

哈希函数

下标=关键字 mod 13

数组

15

2

28

下标

0

1

2

3

4

5

6

7

8

9

10

11

12

(说明:28%13=2,由于下标2被占用,下标换为2+12;28%13=2,下标换为2+22,...同理 )


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%

旧表:下标=关键字mod 7

新表:下标=关键字mod 17

旧表:

6

15

2

24

13

0

1

2

3

4

5

6

新表:

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)。

哈希表的缺点

表越满,性能越差

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。