本文根据《大话数据结构》一书,实现了Java版的一个简单的散列表(哈希表)

基本概念

对关键字key,将其值存放在f(key)的存储位置上。由此,在查找时不需比较,只需计算出f(key)便可直接取得所查记录。这个函数 f() 就叫做散列函数,按这个思想建立的表称为散列表

散列技术即是一种存储方法,又是一种查找方法:

  存储过程:根据关键字key,算出f(key),将记录存放在f(key)的位置上;

  查找过程:根据关键字key,算出f(key),该位置上的值即为要找的记录。

散列函数的构造方法

直接定址法

直接取关键字的线性函数为散列地址:f(key)=a×key+b(a,b为常数)

如:对下表的记录,关键字key取为出生年份,令f(key)=key-1980即可。

数字分析法

分析一组数据,找出其规律,尽可能利用这些数据来构造冲突几率较低的散列地址

如:以员工的手机号码作为关键字,前7位数字基本相同,可以选择后面四位数字作为散列地址。

平方取中法

当无法确定关键字中哪几位分布较均匀时,可以先求出关键字的平方值,然后按需要取平方值的中间几位作为散列地址。

折叠法

将关键字分割成位数相同的几部分,最后一部分位数可以不同,然后取这几部分的叠加和(去除进位)作为散列地址。

除留余数法

最为常用的方法,取关键字被某个不大于散列表表长m的数p除后所得的余数为散列地址。

f(key) = key MOD p,p<=m。

随机数法

选择一随机函数(伪随机),取关键字的随机值作为散列地址,通常用于关键字长度不同的场合。

处理散列冲突的方法

当两个关键字key1和key2不同时,有f(key1)=f(key2),这种现象称为冲突。一般情况下,我们会尽量设计恰当的散列函数减少冲突,但无法完全避免,这就需要对冲突进行处理。

开放寻址法

一旦发生冲突,就去寻找下一个空的散列地址,只要散列表足够大,空的散列地址总能找到,并将记录存入。根据下一个位置的不同,又可分为以下三种:

①线性探测法:

②二次探测法

③随机探测法

再散列函数法

在同义词产生地址冲突时计算另一个散列函数地址,直到冲突不再发生,这种方法不易产生“聚集”,但增加了计算时间。如下图所示(RHi代表不同的散列函数):

链地址法

相同地址的记录存放在一个单链表中,散列表值存储所有同义词子表的头指针。如下图所示:

公共溢出区法

为所有冲突的关键字建立一个公共的溢出区来存放。

代码实现

接下来建立一个简单的散列表,其散列函数采用上述的除留余数法,处理冲突的方法采用开放定址法下的线性探测法

Java代码如下:

package HashTable;/*** 散列表* @author Yongh**/
public class HashTable {int[] elem;int count;private static final int Nullkey = -32768;public HashTable(int count) {this.count = count;elem = new int[count];for (int i = 0; i < count; i++) {elem[i] = Nullkey; // 代表位置为空}}/** 散列函数*/public int hash(int key) {return key % count; // 除留余数法}/** 插入操作*/public void insert(int key) {int addr = hash(key); // 求散列地址while (elem[addr] != Nullkey) { // 位置非空,有冲突addr = (addr + 1) % count; // 开放地址法的线性探测}elem[addr] = key;}/** 查找操作*/public boolean search(int key) {int addr = hash(key); // 求散列地址while (elem[addr] != key) {addr = (addr + 1) % count; // 开放地址法的线性探测if (addr == hash(key) || elem[addr] == Nullkey) { // 循环回到原点或者到了空地址System.out.println("要查找的记录不存在!");return false;}}System.out.println("存在记录:" + key + ",位置为:" + addr);return true;}public static void main(String[] args) {int[] arr = { 12, 67, 56, 16, 25, 37, 22, 29, 15, 47, 48, 34 };HashTable aTable = new HashTable(arr.length);for (int a : arr) {aTable.insert(a);}for (int a : arr) {aTable.search(a);}}
}

  

存在记录:12,位置为:0
存在记录:67,位置为:7
存在记录:56,位置为:8
存在记录:16,位置为:4
存在记录:25,位置为:1
存在记录:37,位置为:2
存在记录:22,位置为:10
存在记录:29,位置为:5
存在记录:15,位置为:3
存在记录:47,位置为:11
存在记录:48,位置为:6
存在记录:34,位置为:9

HashTable

  代码中重点可以看:插入操作是如何处理冲突 以及查找操作是如何判断记录是否存在的。

转载于:https://www.cnblogs.com/yongh/p/9284896.html

【Java】 大话数据结构(13) 查找算法(4) (散列表(哈希表))相关推荐

  1. 算法设计与分析——散列表/哈希表(Hash Table):直接寻址表

    分类目录:<算法设计与分析>总目录 相关文章: ·散列表/哈希表(Hash Table)(一):基础知识 ·散列表/哈希表(Hash Table)(二):直接寻址表 ·散列表/哈希表(Ha ...

  2. 数据结构之查找算法:散列查找

    查找算法:散列查找 思维导图: 散列函数和散列表: 构造散列函数的要求: 构造散列函数的方法: 直接定址法: 除留取余法: 数字分析法: 平方取中法: 折叠法: 解决冲突的方法: 开放定址法: 线性探 ...

  3. 【大话数据结构C语言】62 散列表(哈希表)查找

    欢迎关注我的公众号是[CodeAllen],关注回复[1024]获取精品学习资源 程序员技术交流①群:736386324  程序员技术交流②群:371394777 什么是散列表? 在初中的数学课本中学 ...

  4. 散列表(哈希表)(散列函数构造、处理冲突、查找)

    本文转载自: [1]https://blog.csdn.net/qq_22238021/article/details/78258605 [2]https://blog.csdn.net/duan19 ...

  5. 【数据结构笔记41】散列表/哈希表的性能分享

    本次笔记内容: 11.4 散列表的性能分析 文章目录 平均查找长度 影响冲突产生的三个因素 不同方法的性能 线性探测法查找性能 平方探测法和双散列探测法的查找性能 期望探测次数与装填因子α的关系 分离 ...

  6. 【数据结构】查找算法

    文章目录 查找算法 顺序查找算法 折半查找 分块查找 二叉排序树 平衡二叉树(AVL树) 散列表 哈希函数的构造 处理冲突的方法 哈希查找算法及其实现 查找算法 查找:在数据集合中寻找满足某种条件的数 ...

  7. 数据结构与算法【Java】06---七大查找算法总结

    文章目录 数据结构与算法[Java]06---查找算法总结 1.查找算法简介 1.1.查找的定义 1.2.查找算法分类 1.3.常用查找算法 2.线性查找算法 2.1.线性查找简介 2.2.线性查找代 ...

  8. 【数据结构与算法】散列表

    一.散列表的由来? 1.散列表来源于数组,它借助散列函数对数组这种数据结构进行扩展,利用的是数组支持按照下标随机访问元素的特性. 2.需要存储在散列表中的数据我们称为键,将键转化为数组下标的方法称为散 ...

  9. 数据结构: 插值查找算法

    import java.util.Arrays;// 插值查找算法,也要求数组是有序的 public class InsertValueSearch {public static void main( ...

最新文章

  1. 子元素超出父元素宽高是否会报错?
  2. 在 Delphi 下使用 DirectSound (5): 获取或设置缓冲区的格式:
  3. python jieba分词教程_Python jieba 分词
  4. Leetcode 215. 数组中的第K个最大元素 解题思路及C++实现
  5. Weex-初次见到你
  6. delete in ST05 trace - deletion will also lead to many DB access first
  7. union-find算法分析(1)
  8. cocos lua调用java_【Tech-Lua】Cocos-2dx-Lua调用java的小白教程(三)
  9. FreeRTOS时间管理
  10. python -pymysql的操作
  11. CVE-2019-0708漏洞补丁KB4499175
  12. span 文本内容超过宽度自动换行
  13. 关于SQL Server的日期时间数据类型
  14. 为Eureka Server添加用户认证
  15. 如何给awk传外部参数
  16. 统计学习方法——统计学习基础(一)
  17. 视频的传输方式【转】
  18. alter user mysql_MySQL使用ALTER USER修改密码
  19. matlab三维点云去除背景,一种点云处理三维重建方法与流程
  20. 什么是“荷花定律”?

热门文章

  1. spring配置xml遇到的一些错误,最后修改的版本
  2. linux下in命令
  3. Introduce Intelligence to Your Security Operations
  4. MyEclipse中导入java文件出现乱码问题的解决方法
  5. 中国互联网发展的两个瓶颈
  6. Fully decentralized NFT system towards Metaverse: Next generation Seatlab business model
  7. 奇绩创坛 2021年秋季创业营 反馈:再接再厉
  8. the worries in life: basically two things
  9. 亲测有用的markdown博客生成器
  10. 仿生计算(参考神经网络)2017年考试卷子,考前抱佛脚必备!!中英翻译版本!!