目录
1、散列表
散列表(Hash Table)是一种数据结构,它通过使用散列函数将关键字映射到表中的一个位置,从而实现快速查找。散列表通常被用于实现字典、数据库索引等数据结构,它可以提供关键字的高效插入、查找和删除操作。散列表的实现基于数组,每个元素包含一个键值对(key-value pair)。其中,键通常是一个字符串或整数,值可以是任何类型的数据,例如字符串、整数、对象等。在查找元素时,散列表使用散列函数将关键字转换为数组索引,并在此位置上查找键值对。如果存在,则返回其对应的值;如果不存在,则返回空值。
2、散列函数
2.1 定义
散列函数是一种将输入数据映射到固定大小输出数据的函数。它将不同大小的输入数据转换成相同长度的散列值(也称为哈希值、摘要或指纹),通常用作数据加密、数字签名、消息认证码(MAC)等领域的基础。
散列函数应该满足以下要求:
1. 均匀性:散列函数应该将不同输入数据均匀地映射到输出空间的不同位置,以减少散列冲突的发生。
2. 独立性:输入数据的微小变化应该能够引起输出散列值的大幅度变化,以增强散列函数的安全性。
3. 不可逆性:根据输出散列值无法推导出输入数据,即难以通过散列值反向计算出输入数据。
常见的散列函数算法包括MD5、SHA-1、SHA-2、SHA-3等。但是,由于计算机计算能力的提高和攻击技术的发展,目前常用的算法已不够安全,需要不断更新和升级。
2.2 散列函数的构造
2.2.1 除留余数法
将关键字除以某个数m,取余数作为散列地址,即h(k)=k%m。但是如果m的取值不合适,可能会导致散列地址分布不均匀。m的取值一般是不大于散列表表长的最大质数。
2.2.2 直接定址法
将关键字直接映射为地址,即h(k)=a*k+b(a,b是常数)。但是如果关键字取值范围较大,则需要大量的内存空间。
2.2.3 数字分析法
选取数码分布较为均匀的若干位最为散列地址。
2.2.4 平方取中法
先将关键字平方,然后取中间几位作为散列地址,即h(k)=取中间几位( k^2 )。这种方法能够减小散列地址的值的尺寸,但是也可能出现分布不均匀的问题。
3、冲突(碰撞)
散列表的冲突指的是将两个或多个不同的键映射到了散列表的同一个位置上。这种情况称为冲突,因为两个不同的键无法在同一个位置上存储。
散列表的冲突可以通过散列函数的优化和冲突解决方法来减少或避免。以下是几种常见的冲突解决方法:
- 链接法 (Chaining):将相同位置上的键值对通过链表等数据结构链接在一起。
- 开放地址法 (Open Addressing):在发生冲突时,按照一定规则去寻找数组内的下一个空闲位置存储。
- 双散列法 (Double Hashi