哈希表基础
- 哈希表是一类数据结构(哈希表包含数组、集合和映射,和前两篇文章叙述的字符串、链表平级)
- 哈希表概念:类似于Python里的字典类型,哈希表把关键码key值通过哈希函数来和哈希表上的索引对应起来,之后输入key值可直接定位到对应索引位置,然后进行取值
- 哈希表的好处:主要为查找方便,可快速判断一个元素是否在集合中
- 哈希函数:即关键码key值和存储位置(索引)的对应关系,一个散列函数,比如把小明映射为0,小李映射为1,如图
- 哈希碰撞
- 定义:当哈希函数的映射关系把多个关键码映射到了同一个哈希表索引上时,这种现象称为哈希碰撞,如图所示(哈希碰撞有时候是因为关键码的数量大于哈希表的长度,这时不可避免发生碰撞;但是也可能是哈希函数的对应关系不合理,使得即便仍有空索引,还是把部分关键码分配到了同一索引上)
- 其实发生哈希碰撞不见得是个坏事,如果是因为关键码的数量大于哈希表的长度,说明此时哈希表的所有索引都被完全利用,没有发生内存浪费
- 解决方案一:拉链法
- 当发生冲突时,在对应索引位置通过链表结构储存多个关键码,如图所示
- 当发生冲突时,在对应索引位置通过链表结构储存多个关键码,如图所示
- 解决方案二:线性探测法
- 如果是哈希函数的对应关系不合理,使得即便仍有空索引,还是把部分关键码分配到了同一索引上,此时可以利用线性探测法,从发生冲突的索引位置开始,线性查找找到下一个空索引,然后把多余的关键码分配过去,如图所示
- 如果是哈希函数的对应关系不合理,使得即便仍有空索引,还是把部分关键码分配到了同一索引上,此时可以利用线性探测法,从发生冲突的索引位置开始,线性查找找到下一个空索引,然后把多余的关键码分配过去,如图所示
- 定义:当哈希函数的映射关系把多个关键码映射到了同一个哈希表索引上时,这种现象称为哈希碰撞,如图所示(哈希碰撞有时候是因为关键码的数量大于哈希表的长度,这时不可避免发生碰撞;但是也可能是哈希函数的对应关系不合理,使得即便仍有空索引,还是把部分关键码分配到了同一索引上)
常见的三种哈希表结构
- 列表
- set集合
- 是一种数据结构,常用于元素的查找和去重
- 特点:元素不重复、乱序、可遍历、可变
- 创建方式一:
my_set = {1, 3, 5}
- 创建方式二:
my_set = set()
或列表转集合my_set = set([1, 3, 5])
- 元素查找:使用关键字in,如
if "TOM" in my_set:
- 元素去重:集合结构会进行自动去重操作
- 数学操作:
- 交集,
set1 | set2
将返回二者的交集 - 并集,
set1 & set2
将返回二者的并集 - 差集,
set1 - set2
将返回1中有,2中没有的元素
- 交集,
- 常用方法
- 添加元素,
set.add(data)
- 删除元素,
set.remove(data)
或set.discard()
,当删除集合中不存在的元素时,前者会引起异常,后者不会 - 集合长度,
len(set)
- 清空集合,
set.clear()
- 添加元素,
- map映射