哈希表是什么

本文详细介绍了哈希表的基本概念,包括其作为数据结构的工作原理、如何存储数据并解决哈希冲突,重点讲解了Java HashMap的实现。讨论了开放寻址法和拉链法,以及哈希表的扩容策略和数据查找过程。

一.什么是哈希表

​散列表(Hash table,也叫哈希表),是根据键(Key)而直接访问在内存存储位置的数据结构。也就是说,它通过计算一个关于键值的函数,将所需查询的数据映射到表中一个位置来访问记录,这加快了查找速度。这个映射函数称做散列函数(哈希函数),存放记录的数组称做散列表。 ​

二.哈希表本质

哈希表其实是一种数据结构

哈希表本质上是个数组,底层实现是在数组上然后在加工, 称 哈希表。

1.实现哈希表的方式分为:

        数组+链表

        数组+二叉树

2.以hashMap分析

        1).可以发现hashMap是由 哈希表 实现的,

        2).底层实际上是数组 [], 数组下标对应存储的是Entry(K,V)键值对

3.哈希表是怎么存储数据的

        哈希表是根据KEY值通过 哈希函数  计算得到一个值,这个值是用来确定Entry要存放在哈希表哪个位置的,实际上这个值就是数组的下标值,用来确定放在数组的哪个位置上。

      看图分析: 键值对 Entry<张三,100分>  ,通过对key“张三”采用 哈希函数   计算得到 值0,这个值0就代表了我们应该把 Entry<张三,100分> 放到数组下标等于0的位置上。

        注意:数组中0的位置存放的是一个键值对Entry对象

三.哈希冲突

    哈希冲突/哈希碰撞都是一个意思

   1.为什么会发生

         看图理解为什么发生哈希冲突

        通过上图分析得知,KEY值"张三","李四"通过哈希函数计算都得到了同一个值0,此时就产生了哈希冲突。

         此时下标0的位置已经被键值对Entry<张三,100分>占用了,那李四改怎么办。

2.解决哈希冲突的办法

        关于哈希冲突的解决办法有好几种,这里只介绍两种主要的方法,一个是开放寻址法,一个是拉链法。

1.开放寻址法

        开放寻址法采用的方式是在数组上另外找个新位置

        这里所说的开放寻址法其实简单来说就是,既然位置被占了,那就另外再找个位置,怎么找其他的位置?,其实也有很多的实现,最基本的就是既然当前位置被占用了,我们就看看该位置的后一个位置是否可用,也就是0的位置被占用了,我们就看看1的位置,如果没有被占用,那就放到这里呗,当然,也有可能2的位置也被占用了,那咱就继续往下找,看看3的位置,一次类推,直到找到空位置。

        Java中的ThreadLocal就是利用了开放寻址法。

2.拉链法(hashMap就是采用此法)

      1.拉链法 就是还是在原来下标0的位置上,这里采用的是链表,什么意思呢?就像图中所示,现在张三和李四都要放在0找个位置上,但是张三先来的,已经占了这个位置,待在了这个位置上了,那李四呢?解决办法就是链表,这时候这个0的位置存放的不单单是之前的那个Entry了,此时的Entry还额外的保存了一个next指针,这个指针指向数组外的另外一个位置,将李四安排在这里,然后张三那个Entry中的next指针就指向李四的这个位置,也就是保存的这个位置的内存地址,如果还有冲突,那就把又冲突的那个Entry放在一个新位置上,然后李四的Entry中的next指向它,这样就形成了一个链表。


      2.当冲突过多的时候,这块的链表会变得比较长  ,拿java集合类中的HashMap来说,如果这里的链表长度大于等于8的话,链表就会转换成树结构,当然如果长度小于等于6的话,就会还原链表。以此来解决链表过长导致的性能问题。

        3.这样设计是因为中间有个7作为一个差值,来避免频繁的进行树和链表的转换,因为转换频繁也是影响性能

4.哈希表的扩容

        当初始数组(哈希表) 被占用的位置比较多的时候,出现哈希冲突的概率同时会增高,所以需要进行扩容。

        比如HashMap,HashMap构造一个具有默认初始容量为16和加载因子为0.75(16*0.75容量就会增加容量,不会等到达16)的空HashMap。当它当前的容量占总容量的百分之七十五的时候就需要扩容了。       

        而且这个扩容也不是简单的把数组扩大,而是新创建一个数组是原来的2倍,然后把原数组的所有Entry都重新Hash一遍放到新的数组。

        重新Hash的意思是:因为数组扩大了,所以一般哈希函数也会有变化,这里的Hash也就是把之前的数据通过新的哈希函数计算出新的位置来存放。

5.读取哈希表数据

        

        比如现在要通过“李四”来查找学生的成绩,我们首先通过KEY“李四”利用哈希函数得出位置0,然后我们就去数组下标位置0get数据,拿到这个Entry之后我们需要看看这个Entry的key是不是我们的KEY“李四”,发现是“张三”,这不是我们要的key,然后根据这个Entry的next知道下一给位置,在比较key,成功找到“李四”。

        对于开放寻址那种也是这个思路,先确定到这个位置,然后再看这个位置上的key是不是我们要的,如过不是那就看看下一个位置的。

6.哈希函数是核心

        设计哈希函数的几种方法

        比如有直接定址法,数字分析法,折叠法,随机数法和除留余数法等等

        

        

本文参考下属链接,用自己的理解重新归纳,仅供个人参考。

————————————————————————————————

版权声明:本文为优快云博主「庆哥Java」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/sinat_33921105/article/details/103344078

————————————————————————————————

       

 

<think>首先,用户的问题是:“哈希表是什么样子的”,意思是“哈希表是什么样子的”,所以我需要用中文回答。 关键指令: - 使用中文回答问题。 - 回答完问题后,必须提出3-5个相关问题。 - 相关问题必须以“§§相关问题§§”开头,并在第一行完整输出。 - 相关问题不能换行分散;必须是连续的列表。 - 最后,所有内容必须符合规则。 回答哈希表是什么样子的:我需要解释哈希表的本质和结构。哈希表是一个数据结构,用于存储键值对,通过哈希函数将键映射到桶中。样子上,它可以看作一个数组或列表,每个位置是一个桶,可能包含链表或开放寻址的元素。 结构化回答: 1. 定义哈希表哈希表是一种高效的数据结构,用于存储键值对。 2. 描述样子: - 它通常由一个数组(桶数组)组成。 - 每个桶可以是链表(用于处理哈希冲突)或直接存储元素。 - 例如,在Java中,HashMap的实现是用数组加链表或红黑树。 3. 简单示例:可以用文字描述或伪代码。 4. 保持简洁,因为用户可能在问视觉上的样子。 在回答中,不要使用代码块,除非必要。用户的问题是“是什么样子的”,可能更偏向于概念而非代码。但示例格式中有代码,所以我应该适当描述。 确保中文回答。 之后,添加相关问题:3-5个。必须以“§§相关问题§§”开头,然后列出1. 相关问题1 2. 相关问题2 3. 相关问题3等。 相关问题应该基于用户的问题和我的回答。用户可以问关于哈希表的冲突处理、应用、优缺点等。 脑力storm相关的问题: 1. 哈希冲突是如何处理的? 2. 哈希表的时间复杂度是多少? 3. 哈希表有哪些常见的实现方式? 4. 哈希函数在哈希表中扮演什么角色? 5. 在实际应用中,哈希表常用于哪些场景? 选择3-5个:例如,4个。 输出格式: - 先回答用户的问题。 - 然后,换行后,第一行是“§§相关问题§§”。 - 接着是列表:1. ... 2. ... 3. ... 4. ... 没有换行分散,意思是问题之间不应该有空行,连续输出。 从示例看: ``` §§相关问题§§ 1. ··· 2. ··· 3. ··· ``` 所以,在我的回答后,直接: §§相关问题§§ 1. 问题1 2. 问题2 3. 问题3 4. 问题4 现在,撰写回答: 中文回答哈希表哈希表是一种数据结构,它使用哈希函数将键映射到存储位置(桶),从而实现快速查找、插入和删除键值对。它的样子通常是一个数组,数组的每个元素是一个桶,每个桶可以存储一个或多个键值对。当发生哈希冲突时,桶可能包含链表(链地址法)或使用开放寻址法处理。 为了更生动:想象一个表格,左边是索引(哈希值),右边是存储的值或链表。 添加一个简单描述。 最后,相关问题: 1. 哈希冲突的处理方法有哪些? 2. 哈希表的时间复杂度如何? 3. 在实际编程中,如何实现一个哈希表? 4. 哈希表与数组或链表相比有哪些优势? 确保4个问题。 完整输出。 </think>哈希表是一种基于键值对存储的数据结构,它使用哈希函数将键(key)映射到数组中的特定位置(称为bucket或桶)。其样子通常表现为一个固定大小的数组,数组的每个索引对应一个桶。桶中可以存储一个或多个元素:如果发生哈希冲突(即多个键映射到同一个索引),桶可能包含链表(在链地址法中用于存储多个元素)或直接使用开放寻址法(如线性探测)在相邻位置存储元素。例如,在Java的HashMap实现中,数组的每个元素可能是一个链表或红黑树节点,用于高效处理冲突。整体上,哈希表像一个表格,左边是索引(由哈希函数计算得出),右边是存储的值或冲突元素链。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值