代码随想录算法学习 | 哈希表理论基础

首先什么是 哈希表,哈希表(Hash table,国内也有些算法书籍翻译为散列表)

哈希表是根据关键码的值而直接进行访问的数据结构。

 直白来讲数组就是一张哈希表

哈希表中的关键码就是数组的索引下标,然后通过下标访问数组元素

哈希表能用解决什么问题呢? 一般哈希表都用来快速判断一个元素是否出现在集合里

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

如果学生数量大于哈希表的大小怎么办,此时就算哈希函数计算的再均匀,也避免不了会有几位学生的名字同时映射到哈希表 同一个索引下标的位置

接下来哈希碰撞登场

哈希碰撞

如图所示,小李和小王都映射到了索引下标 1 的位置,这一现象叫做哈希碰撞

一般哈希碰撞有两种解决方法, 拉链法和线性探测法。

拉链法

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

线性探测法

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

常见的三种哈希结构

  • 数组
  • set(集合)
  • map(映射)

数组作为哈希表的缺点是数组大小有限,而且如果哈希值比较少、特别分散、跨度非常大,使用数组就造成空间的极大浪费

std::set 和std::multiset 、std::map 和std::multimap的底层实现是红黑树,红黑树是一种平衡二叉搜索树,所以key值是有序的,但key不可以修改,改动key值会导致整棵树的错乱,所以只能删除和增加。

当我们要使用集合来解决哈希问题的时候,优先使用unordered_set,因为它的读写速度是最快的,如果需要集合是有序的,那么就用set,如果要求不仅有序还要有重复数据的话,那么就用multiset。

map是一个key value的数据结构,map中对key是有限制,对value没有限制,因为key的存储方式使用红黑树实现。

总结

当我们遇到了要快速判断一个元素是否出现在集合里的时候,就要考虑哈希法

  • 若数据的范围已知或者有限,可以考虑使用数组
  • 若数据范围较大,可使用set集合,首选unordered_set;如果需要集合有序,那么用set;如果要求不仅有序还要有重复数据的话,用multiset
  • 若有两个数据需要存储,使用map

但哈希表也是牺牲空间换取了时间,因为我们要使用额外的数组,set或者是map来存放数据,才能实现快速查找。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值