哈希表的学习笔记

昨天晚上,被一道LeetCode上名叫Palindrome Pairs困扰了很久,导致没时间写点什么。

坚持,不管学的多少,争取每天进步一点,记录一点。


今天用到了c++STL的map容器,了解到map容器内部存储是用红黑树,可以使查找访问map中元素的时间从线性结构的O(n)减少到O(logn)。

关于红黑树之前了解较少,今天学习了一部分知识,但还没完全领悟,下次再仔细总结。

----------以上都是废话。。忽略。。。


从O(n)到O(logn),树结构让数据查找更快捷,但树的构造和维护也牺牲了时间,但对于频繁访问的数据,这点牺牲是值得的。

树形结构存储不是查找数据最快的。

最快的是哈希表存储。


哈希表,简单来说,就是把要存储的数据的关键字,通过一个函数映射到对应的有限、连续的内存单元中存储。


举个例子来说:


有数据:char  s[5]={'a' ,'b' ,'c' , 'd' , 'e'}

将每个元素通过 H(x)=(x-‘a’)%5  映射到0,1,2,3,4的内存单元中。

当你要查找‘d’在不在你的s数组里时:

只需计算H( ‘d' )地址4,看这块地址是否有’d‘。

有了哈希表,就比直接遍历s数组快多了。


而这只是理想的运气好的情况。应为会有冲突---------

假设s数组是这样 char  s[6]={'a' ,'b' ,'c' , 'd' , 'e' , ’f‘},

H(x)不变:H(x)=(x-‘a’)%5 ,

那么当存入’f‘时会发现H('f')=0,而0内存单元已经被’a‘占据了。

这就是发生了冲突。


理论上讲哈希表的冲突是不可避免的,但要尽量减少冲突。

当冲突发生了想办法解决冲突。


减少冲突最直接的方法就是,选好用什么哈希函数。常见的哈希函数构造:


1.直接定值:

H(x)=x或者H(x)=a*x+b

这种方法就直接把数据的关键字一对一映射,若没有重复关键字,就没有冲突。

当数据很少,数量有限时适用,但在解决实际问题中用得少。


2.数字分析:

选取数字序列的某几位作为地址。

例如

若有下6个数据:

1234567

1325467

1212567

1267467

1293567

1388467

就可以选第3、4位(一定映射后)作为地址,会比选其他1/2/5/6/7位做地址的冲突少。


3.平方取中:

将数据的关键字平方取中间几位作为地址,这种方法常见。这样能使地址有更高随机性。具体取几位要看哈希表表长。


4.折叠法:

也是常见方法之一。

将数据的关键字折叠:

如有这样一个关键字:12345678

折叠为两位:(s形折叠)

   12

   34

   56

+ 78

----------------

   80


折叠为四位:(c形折叠)

   1234   

+ 8765

----------------

   9999


5.取余法:


最简单、最常用的方法。可以配合平方取中和折叠一起使用。

H(x)=x%d

d取值非常重要!这个方法的好坏就取决于d。

常见的d取质数或者 不包含小于20质因数的合数


6.随机数生成:

用一个随机函数,取关键字的随机函数值作为地址。

适用于关键字位数或者形式不同的情况。



而解决冲突的发放也有几种。(电脑没电了,下次继续)





  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
尚硅谷数据结构韩顺平老师在讲解数据结构时也提到了哈希表哈希表是一种常用的数据结构,它通过哈希函数将关键字映射到一个数组中的位置,以实现快速的查找和插入操作。哈希表的特点是可以在常数时间内进行查找、插入和删除操作,因此在实际应用中被广泛使用。 然而,哈希表也有一些不足之处。首先,哈希表中的数据是没有顺序的,所以不能以一种固定的方式来遍历其中的元素。其次,通常情况下,哈希表中的key是不允许重复的,不能放置相同的key,用于保存不同的元素。 尽管哈希表存在一些不足之处,但是它在实际应用中的性能优势仍然是非常显著的。在处理大量数据时,哈希表可以提供较高的查找效率,使得我们能够更快地找到所需的数据。 因此,尚硅谷数据结构韩顺平老师在讲解数据结构时也强调了哈希表的重要性,帮助学习者了解并掌握这一常用的数据结构。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [韩顺平老师尚硅谷Java数据结构与算法194集笔记](https://download.csdn.net/download/weixin_52184392/32076811)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [【尚硅谷|韩顺平】数据结构和算法](https://blog.csdn.net/ZEZHEN0222/article/details/128624496)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [数据结构与算法-哈希表 | 尚硅谷韩顺平](https://blog.csdn.net/weixin_54232666/article/details/127043618)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值