博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
数据结构之「哈希表」
阅读量:6412 次
发布时间:2019-06-23

本文共 1535 字,大约阅读时间需要 5 分钟。

什么是哈希表?

哈希表(Hash Table, 也叫散列表),是根据键(Key)来直接访问在内存存储位置的数据结构。它通过一个哈希函数将所需要查询的数据映射到一张哈希表中,来提升查询效率。

哈希函数的实现方法:
1.取余法
取关键字被某个不大于哈希表表长的数除后所得的余数为散列地址。
2.折叠法
将关键字分割成位数相同的几部分(最后一部分的位数可以不同),然后取这几部分的叠加和(舍去进位)作为哈希地址。
3.平方取中法
取关键字平方后的中间几位为哈希地址。
4.直接定址法
取关键字或关键字的某个线性函数值为哈希地址。

哈希冲突

不管用什么哈希函数去计算哈希地址,都是会产生哈希冲突的,因此我们需要想办法解决哈希冲突,并且在设计哈希函数时,尽可能减少哈希冲突。

1.单独的链表法
在哈希表的后面单独链上一个单链表来存储冲突的元素,JDK 1.8 里的 HashMap 就是选择的这种方式解决冲突的,不过它对链表做了一层优化。当元素个数大于等于 8 时,会把链表转换成红黑树,提升查询效率。
2.线性探测法
当发生哈希冲突时,逐个探测存放地址的表,直到查找到一个空单元。这个方式不便于查找,不建议使用。
3.建立一个公共溢出区
当发生哈希冲突时,就把元素存入到公用的溢出区,查询时遍历溢出区。
从上面这几种处理方法来说,还是链表法效率比较高,推荐使用。不过都有现成的工具类使用,因此只需要知道实现原理,最好自己可以去写代码实现它。

哈希表有什么用?

哈希表在日常开发中还是比较常用的,因为它最优的查询时间复杂度是 O(1),当哈希冲突比较严重的时候,查询效率就相当于线性的,因此哈希算法直接影响到查询的效率。

哈希表怎么实现的?

哈希表的结构

public class HashMap
{ //用节点数组当作哈希表 Node
[] table; int size; //节点 static class Node
{ //哈希值 final int hash; //键 final K key; //值 V value; //哈希值冲突时存储 Node
next; Node(int hash, K key, V value, Node
next) { this.hash = hash; this.key = key; this.value = value; this.next = next; } }}复制代码

总结

哈希表是一个键值对的存储结构,并且根据键进行哈希算法找到对应的存储位置。哈希算法会直接影响到哈希表的查询效率,一般选择哈希冲突小的实现方式,以便提升查询效率。当哈希冲突时,一般选择链表来存储冲突的元素,当冲突的元素增多时,可以采用红黑树来存储,以提升查询效率。JDK 1.8 版本的 HashMap,当链表个数大于等于 8 时,就是采用红黑树来存储的。在知道元素个数时,初始化哈希表时直接指定哈希表大小,因为当元素达到哈希表大小时,会做 resize 操作。当元素越来越多时,resize 是很耗时的,相当于重建哈希表。因此直接指定哈希表大小,减少 resize 次数以便提升插入性能。

转载地址:http://mzura.baihongyu.com/

你可能感兴趣的文章
caffe 画loss曲线
查看>>
innodb系统表空间维护
查看>>
从头开始写框架(二):孕育框架的种子_下
查看>>
4-数据类型(2)
查看>>
百度图片爬虫
查看>>
cocos2dx 3.2之Lua打飞机项目
查看>>
JAVA- JDBC之DBHelper
查看>>
AQS同步组件及ReentrantLock和synchronized的区别
查看>>
bzoj1901: Zju2112 Dynamic Rankings 主席树+树状数组
查看>>
jeewx的使用_01 接入和验证
查看>>
java.net.BindException: Address already in use:80 linux
查看>>
用javascript向一个网页连接接口发送请求,并接收该接口返回的json串
查看>>
PHP语言 -- Smarty缓存
查看>>
谈谈JavaScript中function多重理解
查看>>
窗口置顶 - 仿TopWind
查看>>
(转)通过注册表修改VC6.0的字体
查看>>
oracle 查询 函数练习2
查看>>
浅析如何学习基于ARM平台的嵌入式系统(转载)
查看>>
AQS(AbstractQueuedSynchronizer)应用案例-02
查看>>
Javascript-闰年javascript的判断
查看>>