哈希表总结点睛

一、哈希表

1、名称

又称 散列表、 Hash table。哈希表就是根据关键吗的值而直接进校访问的数据结构

其实数组就是一张哈希表,数组的索引为key,数组的元素为value。

数据规模是dataSize, 哈希表的大小为tableSize

  • 哈希表 是一种数据结构,它是使用哈希函数,也就是散列函数组织数据,将健 映射到特定的桶,支持快速插入和搜索

  • 散列函数 取决于 健值的范围 和 桶的数量

  • 哈希函数的设计思想是尽可能将键分配到桶中,理想情况下,完美的哈希函数将是键和桶之间的一对一映射。然而,在大多数情况下,哈希函数并不完美,它需要在桶的数量和桶的容量之间进行权衡。

2、哈希表能解决什么问题呢?

  • 一般是用来快速判断一个元素是否出现集合里。

3、哈希碰撞

哈希碰撞有两种解决办法:

1、拉链法:拉链法就是要选择适当的哈希表的大小,这样既不会因为数组空值而浪费大量内存,也不会因为链表太长而在查找上浪费太多时间。

2、线性探测法:使用线性探测法,一定要保证tableSize大于dataSize。我们需要依靠哈希表中的空位来解决碰撞问题。

以 将学生姓名映射到哈希表 为例:

hash function 哈希函数:把学生姓名直接映射到哈希表上的索引,然后就可以通过查询索引

表快速知道某位同学是否在这所学校里。

hash code: 是通过特定编码方式,可以将其他数据格式转化为不同的数值。这样就把学生名字映射为哈希表上的索引数字了。

哈希碰撞:小李和小王都映射到同一个索引表的位置上

拉链法:发生冲突的元素都被存储在链表中。即将小李和小王都存储在同一个索引表上。

线性探测法:冲突的位置,放了小李,那么就向下找一个空位放置小王的信息。

3、哈希表常见的三种结构:

  • 数组
  • set(集合)
  • map(映射)
图片 图片
总结一:六种容器

在C++语言中,set 分别提供了三种数据结构:
set
multiset
unordered_set

在C++语言中,map 分别提供了三种数据结构:
map
multimap
unordered_map

总结二:底层实现

底层实现为哈希表:unordered_set、unordered_map
底层实现为红黑树:set,multiset,map,multimap 注意:只能删除和增加

红黑树是一种平衡二叉搜索树,所以key值是有序的,但key不可以修改,改动key值会导致整棵树的错乱,所以只能删除和增加。

总结三:使用规律

当我们要使用集合来解决哈希问题的时候,
1、优先使用unordered_set,因为它的查询和增删效率是最优的,
2、如果需要集合是有序且没有重复的,那么就用set,
3、如果要求不仅有序还要有重复数据的话,那么就用multiset。

虽然set、multiset 的底层实现是红黑树,不是哈希表,但是set、multiset 依然使用哈希函数来做映射,只不过底层的符号表使用了红黑树来存储数据,所以使用这些数据结构来解决映射问题的方法,我们依然称之为哈希法。map也是一样的道理。

总结四:数组&哈希
  数组可以当做哈希表来用:
  但是当哈希值比较少,特别分散,跨度非常大时,使用数组就造成空间的极大浪费
总结五:有序&无序

对哈希表的无序的理解:

1、什么是无序,什么是有序?

所谓有序和无序,是是否按关键字的输入顺序保存元素。

无序指的是不按你给的信息去排序,哈希表有一个哈希函数,通过哈希函数可以把 key 转为 index ,所以哈希表的底层其实是一个 array + list 链表。array 的 index 就是 key 经过哈希之后转换成的,然后再把 key 和 value 放进链表里。因此称之为无序。

无序的是unordered_map、 unordered_set。 采用迭代器遍历出来的元素是无序的, 这是因此底层实现数据结构为哈希表。

有序是指:使用迭代器遍历的时候,按照输入的顺序

比如:

unordered_set set1;

set set2;

在set1和 set2 中都输入 a b c则有:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值