HashTable详解

散列表(Hash table,也叫哈希表),是根据Key value而直接进行访问的数据结构。它通过把关键码值映射到表中一个位置来访问记录(类似索引),以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表

哈希表结构示例

1、数组+链表

2、数组+二叉树(链表树化)

google公司的一个上机题:

有一个公司,当有新的员工来报道时,要求将该员工的信息加入(id,性别,年龄,名字,住址…),当输入该员工的id时,要求查找到该员工的所有信息.

要求:
不使用数据库,速度越快越好=>哈希表(散列)
添加时,保证按照id从低到高插入 课后思考:如果id不是从低到高插入,但要求各条链表仍是从低到高,怎么解决?
使用链表来实现哈希表, 该链表不带表头[即: 链表的第一个结点就存放雇员信息]
思路分析并画出示意图
代码实现[增删改查(显示所有员工,按id查询)]





public class HashTab {class Emp{public int id;public String name;public Emp next;public Emp(int id, String name) {super();this.id = id;this.name = name;}}class EmpLinkedList{//链表private Emp head;public void add(Emp emp){if(head==null){head=emp;return;}Emp curEmp=head;while (true){if(curEmp.next==null){break;}curEmp=curEmp.next;}curEmp.next=emp;}public void list(){if(head==null){System.out.println("kong");return;}System.out.println("为");Emp curEmp=head;while (true){System.out.println(curEmp.id+curEmp.name);if (curEmp.next==null){break;}curEmp=curEmp.next;}System.out.println("完了");}}
}

哈希表查找原理

哈希函数

哈希函数其实就是我们常说的哈希算法,主要应用在以下这几个方面:文件校验、数字签名、鉴权协议。常用的哈希算法有以下这些。
<1>MD5:MD5即Message-Digest Algorithm 5(信息-摘要算法5),用于确保信息传输完整一致。MD5是输入不定长度信息,输出固定长度128bits的算法。
<2>SHA-1:常用于HTTPS传输和软件签名
<3>SHA-2:SHA-224/SHA-256/SHA-384/SHA-512并成为SHA-2
<4>SHA-3:之前名为Keccak算法,是一个加密杂凑算法

哈希函数设计的足够好的话,就会减少哈希冲突的概率

如何避免哈希冲突

当不同的键生成了相同的索引的时候-----》 处理冲突------》拉链法和线性探索法。

拉链法

将大小为M的数组的每一个元素指向一个链表,链表中的每一个节点都存储散列值为该索引的键值对,这个就是拉链法。
”John Smith”和”Sandra Dee”通过哈希函数指向152这个索引该索引又指向了一个链表,在链表中依次存储了这两个字符串
该方法的基本思想就是选择足够大的M,使得所有的链表都尽可能的短小,以保证查找的效率。对采用拉链法的哈希表实现的查找分为两步,首先是根据散列值找到对应的链表,然后沿着链表的顺序找到相应的键。


线性探索法

线性探测法是开放寻址法解决哈希冲突的一种方法,基本原理为,使用大小为M的数组来保存N个键值对,其中M>N,我们需要使用数组中的空位来解决碰撞冲突

对照前面的拉链法,在该图中,”Ted Baker”有唯一哈希值153的,但是由于153被”Sandra Dee”占用了。而原先”Sandra Dee”和”John Smith”的哈希值都是152的,但是在对”Sandra Dee”进行哈希的是偶发现152已经被占用了,所以往下找发现153没有被占用,就将其存放在153。后面”Ted Baker”哈希到153上,发现被占用了,就会往下找,发现154没有被占用,所以将其存放到154上面。

开放寻址法中最简单的是线性探测法:当碰撞发生时即一个键的散列值被另外一个键占用时,直接检查散列表中下一个位置,即将索引值加1,这样的线性探测有三种结果:

<1>命中,该位置的键个被查找的键相同

<2>未命中,键为空

<3>继续查找,该位置的键和被查找的键不同

拉链法和线性探索法对比

那个这两种方法的性能上面有什么区别?对于拉链法,查找的效率在于链表的长度,一般我们应该保证长度的M/8-M/2之间,如果链表的长度大于M/2,我们可以扩充数组长度。如果长度在0~M/8时,我们可以缩短数组的长度。对于线性探索法,动态调整数组的大小需要对所有的值重新进行散列并插入新的表中

不管是拉链法还是散列法,这种动态调整链表或者数组的大小以提高查询效率的同时,还应该考虑动态改变链表或者数组大小的成本。散列表长度加倍的插入需要进行大量的探索,这种均摊成本很多时候需要考虑。

哈希碰撞

不管是采用拉链法还是开放寻址法解决冲突,在后面查找的时候都需要进行多次探测或者查找,在很多时候会使得哈希表的查找效率退化,而不再是常数时间。如下图描述的那样。

哈希攻击就是通过精心构造哈希函数,使得所有的键进过函数函数后都会映射到同一个或者几个索引上,将哈希表退化为一个单链表,这样哈希表的各种操作,比如插入、查找都会从O(1)退化到了链表的查找操作,这样会消耗大量的CPU资源,导致系统无法响应,从而达到拒绝服务供给(Denial of Service,DOS)的目的。

HashTable详解(图文有代码)相关推荐

  1. 坐标移动c语言,C语言 坐标移动详解及实例代码

    搜索热词 题目描述 开发一个坐标计算工具, A表示向左移动,D表示向右移动,W表示向上移动,S表示向下移动.从(0,0)点开始移动,从输入字符串里面读取一些坐标,并将最终输入结果输出到输出文件里面. ...

  2. 并查集详解 ——图文解说,简单易懂(转)特别好玩

    并查集详解 --图文解说,简单易懂(转) 2016年03月10日 17:38:08 阅读数:6931 标签: 并查集数据结构并查集算法图文解说 更多 个人分类: 算法--并查集 并查集是我暑假从高手那 ...

  3. python随机数程序源码_Python 实现随机数详解及实例代码

    Python3实现随机数 random是用于生成随机数的,我们可以利用它随机生成数字或者选择字符串. random.seed(x)改变随机数生成器的种子seed. 一般不必特别去设定seed,Pyth ...

  4. java super实例_java Super 用法详解及实例代码

    java Super 用法详解及实例代码 发布于 2021-1-8| 复制链接 摘记: java  Super 用法详解 1)有人写了个很好的初始化属性的构造函数,而你仅仅想要在其中添加另一些自己新建 ...

  5. JavaScript 身份证号有效验证详解及实例代码

    这篇文章主要介绍了JavaScript 身份证号有效验证详解及实例代码的相关资料,需要的朋友可以参考下 JavaScript验证身份证号 1 2 3 4 5 6 7 8 9 10 11 12 13 1 ...

  6. 希尔排序基础java代码_java 算法之希尔排序详解及实现代码

    摘要:这篇Java开发技术栏目下的"java 算法之希尔排序详解及实现代码",介绍的技术点是"希尔排序详解.实现代码.希尔排序.Java.实现.代码",希望对大 ...

  7. 超轻量级DI容器框架Google Guice与Spring框架的区别教程详解及其demo代码片段分享...

    超轻量级DI容器框架Google Guice与Spring框架的区别教程详解及其demo代码片段分享 DI框架 Google-Guice入门介绍 转载于:https://www.cnblogs.com ...

  8. Java 线程池详解及实例代码

    转载自  Java 线程池详解及实例代码 这篇文章主要介绍了Java 线程池的相关资料,并符实例代码,帮助大家学习参考,需要的朋友可以参考下 线程池的技术背景 在面向对象编程中,创建和销毁对象是很费时 ...

  9. mysql 字段 as_mysql 字段as详解及实例代码

    mysql 字段使用as 在mysql中,select查询可以使用AS关键字为查询的字段起一个别名,该别名用作表达式的列名,并且别名可以在GROUP BY,ORDER BY或HAVING等语句中使用. ...

最新文章

  1. Git使用4:Git分支
  2. kali linux 安装 Mysql Can‘t read from messagefile 报错解决方案
  3. 欠薪解决新途径:劳动者可向法院申请支付令。(拖欠工资就是违法)
  4. php 字符串包含另一个字符串_leetcode1433_go_检查一个字符串是否可以打破另一个字符串...
  5. 我想在 2012 储备的技术
  6. 【性能测试】如何用一条命令完全掌握linux系统性能监控(top高阶用法)
  7. 从0到1写RT-Thread内核——临界段的保护
  8. 缓存服务的更新策略有哪些?
  9. Moses Staff攻陷以色列网络并加密数据,拒绝谈判
  10. 【渝粤教育】国家开放大学2018年秋季 2208T政治学原理 参考试题
  11. 各大浏览器的最小字体与默认字体
  12. a标签下载文档 a下载文档失败问题 跨域调用
  13. 丹佛斯变频器al14故障代码_丹佛斯变频器故障说明
  14. mysql索引类型normal,unique,full text,索引方式btree索引和hash
  15. 强烈推荐收藏!3W 字Python 操作 Excel 报表自动化指南
  16. JUC- 常用辅助类
  17. unity Layer CullingMask
  18. Striped64 与 LongAdder
  19. 华为v30怎么升级鸿蒙系统,这四款华为手机可升级到鸿蒙系统,老机型居多,最低只需千元!...
  20. clover写入efi_clover如何使用UEFI引导和EFI驱动选择

热门文章

  1. 制作热门活动页面html,第七章 制作热门活动页面练习.html
  2. JavaScriptTXT
  3. lifecycle基本使用
  4. 回归树算法原理及实现
  5. 每日一个小技巧:1分钟告诉你如何给黑白照片上色
  6. WindowsErrorCode
  7. combotree 可以异步加载吗_combotree怎么设置默认值
  8. Android渲染画面,Android系统图像渲染简介
  9. 学历不代表能力,但学历不够就意味着没资格!
  10. 一眼看懂promise与async await的区别