数据结构程序设计——哈希表的应用(2)->哈希表解决冲突的方法
目录
实验须知
代码实现
实验报告
一:问题分析
二、数据结构
1.逻辑结构
2.物理结构
三、算法
(一)主要算法描述
1.用除留余数法构造哈希函数
2.线性探测再散列法
(一)主要算法实现代码
四、上机调试
实验须知
实验目的: 深入理解哈希表解决冲突的办法。实验内容: 针对自己所在班级中学生姓名设计一个哈希表,使得平均查找长度不超过 R ,并完成相应的建表和查表程序。实验要求:( 1 )创建名为 kcsj19.cpp 的文件,在其中编写哈希查找学生姓名的程序;( 2 )假设学生姓名为中国人姓名的汉语拼音形式。待填入哈希表的学生姓名共有 30 个,取平均查找 长度的上限为 2 。哈希函数用除留余数法构造,用线性探测再散列法或链地址法处理冲突;( 3 )测试数据:取读者周围较熟悉的 30 个学生姓名。
代码实现
import java.util.Arrays;
import java.util.Scanner;public class Kcsj19 {private static final int TABLE_SIZE = 61; // 哈希表的大小,选择质数可以减少冲突private String[] table;public Kcsj19() {table = new String[TABLE_SIZE];Arrays.fill(table, "");}// 哈希函数:除留余数法private int hashFunction(String key) {int hashValue = 0;for (char ch : key.toCharArray()) {hashValue = (hashValue * 31 + ch) % TABLE_SIZE;}return hashValue;}// 线性探测再散列法private int linearProbe(int index, int attempt) {return (index + attempt) % TABLE_SIZE;}// 插入元素private void insert(String name) {int index = hashFunction(name);int attempt = 0;while (!table[index].isEmpty()) {attempt++;index = linearProbe(index, attempt);}table[index] = name;}// 查找元素private boolean search(String name) {int index = hashFunction(name);int attempt = 0;while (!table[index].isEmpty()) {if (table[index].equals(name)) {System.out.println("学生姓名 " + name + " 在哈希表中。");return true;}attempt++;index = linearProbe(index, attempt);}System.out.println("学生姓名 " + name + " 不在哈希表中。");return false;}// 打印哈希表private void displayTable() {for (int i = 0; i < TABLE_SIZE; i++) {if (!table[i].isEmpty()) {System.out.println("哈希表[" + i + "]: " + table[i]);}}}public static void main(String[] args) {Kcsj19 hashTable = new Kcsj19();// 待填入哈希表的学生姓名String[] students = {"蔡开俊", "陈恒", "陈慧强", "董彪", "冯迪", "冯伟宇", "谷婉如","韩欣言", "何继翔","李宝才", "李琳琳", "李现珍", "李向阳", "李毅琛", "路亚博","路政睿" ,"孙志坤","王龙杰","王蕊", "王艺涵", "薛获宇", "元亚捷", "岳婧婧", "詹思航", "张浩","张恒", "张佳熙", "张锦彩", "张梦娇", "张轩硕"};// 插入学生姓名到哈希表for (String student : students) {hashTable.insert(student);}// 打印哈希表hashTable.displayTable();// 测试查找学生姓名Scanner scanner = new Scanner(System.in);// 判断学生姓名是否存在于哈希表中while(true) {System.out.print("请输入学生姓名(输入exit退出):");String inputName = scanner.nextLine();if (inputName.equalsIgnoreCase("exit")) {System.out.println("程序已退出。");break;}hashTable.search(inputName);}}
}
实验报告
一:问题分析

描述问题该实验可归结为哈希表的建表和查表功能的实现。用除留余数法构建哈希表,把学生姓名以汉语拼音的形式储存在哈希表中,当发生冲突时,会使用线性探测再散列法在哈希表中的下一个位置继续搜索直到找到空槽。解决该问题的方法和思路:使用除留余数法构造哈希表,然后向表中添加学生姓名,如果在插入和查找的过程中发生冲突用线性探测散列法解决冲突。
二、数据结构
1.逻辑结构
哈希表的应用实习项目的逻辑结构是一个大小为TABLE_SIZE的数组,每个数组元素都可以存储一个学生姓名。哈希函数将学生姓名转化成一个数组索引,然后在该索引位置上插入或查找学生姓名。当插入学生姓名时,如果对应的数组索引位置已经被占用,则使用线性探测再散列法来寻找下一个可用的位置。当查找学生姓名时,根据哈希函数得到学生姓名对应的数组索引,然后根据线性探测再散列法依次检查该索引位置及其后续位置,直到找到匹配的学生姓名或者遇到空位置为止。
2.物理结构
物理结构采用的是顺序存储结构。
三、算法
(一)主要算法描述
1.用除留余数法构造哈希函数
(1)哈希函数的输入是一个字符串key,它使用了一个for循环遍历 字符串key的每个字符,并结合当前的哈希值hashValue进行计算。具体的计算公式是:hashValue=(hashValue * 31+ch)%TABLE_SIZE。
(2)其中,ch表示当前字符的ASCII值。乘以31是为了增加哈希函数的散列性能,使得不同的字符组合能够得到不同的哈希值。最后取余数TABLE_SIZE 是将哈希值限定在哈希表的大小范围内,以确保插入和查询的正确性。
(3)然后,根据这个哈希值,确定存储学生姓名的位置(索引)在哈希表中的哪个位置。最终,将学生姓名保存在哈希表的相应位置上。
2.线性探测再散列法
(1)代码中使用了线性探测再散列法来处理哈希冲突。在插入元素和查找元素的方法中,通过不断尝试下一个位置来解决冲突。如果当前位置已经被占用,就尝试下一个位置,直到找到一个空闲的位置或者遍历完整个哈希表。
(2)linearProbe方法接受两个参数:index表示原始的哈希值对应的索引,attempt表示当前的探测次数。通过将原始索引index和探测次数attempt相加,并对TABLE_SIZE取模,得到一个新的索引值。这个新的索引值即为通过线性探测法计算得到的下一个位置。
(3)在插入元素的方法中,先把通过学生姓名计算出的哈希值赋值给index,此时设置探测次数attempt为0,如果哈希表在index位置不为空那么attempt加一,再用linearProbe方法来计算下一个位置,即(index+attempt) % TABLE_SIZE。如果哈希表在index位置为空的话,就把学生姓名添加到哈希表中。
(4)在查找元素的方法中,首先通过调用hashFunction 哈希函数来计算给定学生姓名的哈希值,并将其赋值给index变量。然后,设置初始的探测次数attempt 为0。接下来,使用一个循环来判断哈希表在index位置是否为空。如果不为空,则进入循环体。在循环体中,首先判断哈希表在index位置的值与目标姓名是否相等。如果相等,说明找到了目标姓名,将相关信息打印出来,并返回true表示找到了目标。如果不相等,则增加attempt的值,并使用linearProbe方法计算下一个探测位置。linearProbe方法使用线性探测再散列法的思想,通过(index + attempt)%TABLE_SIZE的计算来获取下一个探测位置。当哈希表在index位置为空时,说明未找到目标姓名,将相关信息打印出来,并返回false表示未找到目标。
(一)主要算法实现代码
1.用除留余数法构建哈希表
private int hashFunction(String key) {int hashValue = 0;for (char ch : key.toCharArray()) {hashValue = (hashValue * 31 + ch) % TABLE_SIZE;}return hashValue;}
2.线性探测再散列法解决冲突
private int linearProbe(int index, int attempt) {return (index + attempt) % TABLE_SIZE;
}
3.向哈希表中插入元素
private void insert(String name) {int index = hashFunction(name);int attempt = 0;while (!table[index].isEmpty()) {attempt++;index = linearProbe(index, attempt);}table[index] = name;
}
4.在哈希表中查找元素
private boolean search(String name) {int index = hashFunction(name);int attempt = 0;while (!table[index].isEmpty()) {if (table[index].equals(name)) {System.out.println("学生姓名 " + name + " 在哈希表中。");return true;}attempt++;index = linearProbe(index, attempt);}System.out.println("学生姓名 " + name + " 不在哈希表中。");return false;}
四、上机调试
问题1: 输入exit并不会退出程序,而是输出“学生姓名exit不在哈希表中”。

图2 无法退出程序
解决办法:出现这种情况的原因是使用“==”来判断两个字符串是否相等,要比较两个字符串的内容是否相等,可以使用equals方法,或者equalsIgnoreCase方法(可以忽略大小写)。

图3 使用equalsIgnoreCase方法比较字符串是否相同
问题2:哈希表的存储与哈希值有关, 如何获取字符串的哈希值, 进行存储。
解决办法:对于输入的字符串key,遍历其中的每个字符ch,将hashValue乘以31后加上ch的ASCII码值,并取模TABLE_SIZE,得到新的哈希值。
问题3: 出现空指针异常。

图4出现空指针异常
解决办法:出现异常的原因是没有对数组进行初始化。使用Arrays.fill()方法将数组中所有元素赋值为空字符串,避免在插入或查找元素时出现值null, 因为如果数组元素为null,那么在调用字符串方法时,就会抛出空指针异常。

图5对数组进行初始化
相关文章:
数据结构程序设计——哈希表的应用(2)->哈希表解决冲突的方法
目录 实验须知 代码实现 实验报告 一:问题分析 二、数据结构 1.逻辑结构 2.物理结构 三、算法 (一)主要算法描述 1.用除留余数法构造哈希函数 2.线性探测再散列法 (一)主要算法实现代码 四、上机调试 实…...
微信小程序开发系列-07组件
微信小程序开发系列目录 《微信小程序开发系列-01创建一个最小的小程序项目》《微信小程序开发系列-02注册小程序》《微信小程序开发系列-03全局配置中的“window”和“tabBar”》《微信小程序开发系列-04获取用户图像和昵称》《微信小程序开发系列-05登录小程序》《微信小程序…...
JavaScript 中 Set 和 Map 的区别
JavaScript 中的 Set 和 Map 都是用来存储数据的数据结构,它们之间的区别如下: Set 是一组唯一值的集合,而 Map 是一组键值对的集合。Set 中的值是唯一的,不允许重复;Map 中的键是唯一的,值可以重复。Set …...
web前端之JavaScript
MENU JavaScript之设计模式、单例、代理、装饰者、中介者、观察者、发布订阅、策略JavaScript之数组静态方法的实现、reduce、forEach、map、push、every JavaScript之设计模式、单例、代理、装饰者、中介者、观察者、发布订阅、策略 单例模式 概念 保证一个类仅有一个实例&am…...
C# 图标标注小工具-查看重复文件
目录 效果 项目 代码 下载 效果 项目 代码 using System; using System.Collections.Generic; using System.Data; using System.IO; using System.Linq; using System.Security.Cryptography; using System.Windows.Forms;namespace ImageDuplicate {public partial clas…...
浅谈冯诺依曼体系和操作系统
🌎冯诺依曼体系结构 文章目录 冯诺依曼体系结构 认识冯诺依曼体系结构 硬件分类 各个硬件的简单认识 输入输出设备 中央处理器 存储器 关于内存 对冯诺依曼体系的理解 操作系统 操作系统…...
Good Bye 2023
Good Bye 2023 Good Bye 2023 A. 2023 题意:序列a中所有数的乘积应为2023,现在给出序列中的n个数,找到剩下的k个数并输出,报告不可能。 思路:把所有已知的数字乘起来,判断是否整除2023,不够…...
多开工具对手机应用响应速度的优化与改进
多开工具对手机应用响应速度的优化与改进 摘要: 如今,手机应用的多样化和个性化需求不断增长,用户对应用的响应速度要求也越来越高。为了满足用户的需求,开发者们使用了多种技术手段进行应用的优化和改进。其中,多开工…...
文件批量整理,文件归类整理,文件批量归类
我们每天都要面对无数的文件,从工作报告、个人照片到电影和音乐。如何有效地管理和归类这些文件,成为了我们日常生活和工作中所要处理的。今天,小编就给大家介绍一款简单易用的工具——文件批量改名高手,助你轻松实现文件批量归类…...
Python+Django+Mysql+SimpleUI搭建后端用户管理系统(非常详细,每一步都清晰,列举了里面所有使用的方法属性)
一、在Anaconda环境下创建虚拟环境 (1)打开Anaconda Prompt(install),创建虚拟环境,如下图所示: 方法一:默认情况下虚拟环境创建在Anaconda安装目录下的envs文件夹中 conda create --name usermanage …...
【Qt-QWidget-QLabel-QFrame-QSlider-View-Bar】
Qt编程指南 ■ Label■ QLabel■ QMovie 显示动画■ Widget■ QWidget■ QTabWidget■ QTableWidget■ QListWidget■ QStackedWidget■ QCalendarWidget■ QFrame■ QFrame■ View■ QT...
11|代理(上):ReAct框架,推理与行动的协同
11|代理(上):ReAct框架,推理与行动的协同 在之前介绍的思维链(CoT)中,我向你展示了 LLMs 执行推理轨迹的能力。在给出答案之前,大模型通过中间推理步骤(尤其…...
毫秒格式化
## 计算当前毫秒数: const [start,setStart] useState(new Date().getTime())useEffect(()>{setInterval(()>{setCurrMill(new Date().getTime()-start)},1)},[]) ## 格式化毫秒 function formatMilliseconds(milliseconds) {const totalSeconds Math.flo…...
pytorch与cuda版本对应关系汇总
pytorch与cuda版本关系 cuda版本支持pytorch版本cuda10.21.5 ~ 1.12cuda11.01.7 ~ 1.7.1cuda11.11.8 ~ 1.10.1cuda11.31.8.1 ~ 1.12.1cuda11.61.12.0 ~ 1.13.1cuda11.71.13.0 ~ 2.0.1cuda11.82.0.0 ~ 2.1.1cuda12.12.1.0 ~ 2.1.1 cuda 与 cudnn关系 cuda版本支持cudnn版本cu…...
Linux系统下隧道代理HTTP
在Linux系统下配置隧道代理HTTP是一个涉及网络技术的话题,主要目的是在客户端和服务器之间建立一个安全的通信通道。下面将详细解释如何进行配置。 一、了解基本概念 在开始之前,需要了解几个关键概念:代理服务器、隧道代理和HTTP协议。代理…...
unity学习笔记----游戏练习03
一、修复植物种植的问题 1.当手上存在植物时,再次点击卡片上的植物就会在手上添加新的植物,需要修改成只有手上没有植物时才能再次获取到植物。需要修改AddPlant方法。 public bool AddPlant(PlantType plantType) { //防止手上出现多个植…...
VistualStudio查看类图UML
点击菜单栏中的工具–》获取工具和功能。 然后在资源管理器中对应的代码中鼠标右键选择查看类图 生成一个ClassDiagram.cd文件就是类图的文件了。 根据需要拖拽就可以生成类图了。...
elasticsearch系列九:异地容灾-CCR跨集群复制
概述 起初只在部分业务中采用es存储数据,在主中心搭建了个集群,随着es在我们系统中的地位越来越重要,数据也越来越多,针对它的安全性问题也越发重要,那如何对es做异地容灾呢? 今天咱们就一起看下官方提供的…...
基于Java网上点餐系统设计与实现
博主介绍: ✌至今服务客户已经1000、专注于Java技术领域、项目定制、技术答疑、开发工具、毕业项目实战 ✌ 🍅 文末获取源码联系 🍅 👇🏻 精彩专栏 推荐订阅 👇🏻 不然下次找不到 Java项目精品实…...
公司电脑文件加密系统——防止内部核心文件数据 | 资料外泄,自动智能透明加密保护
一套从源头上保障企业电脑数据安全和电脑使用安全的加密软件。天锐绿盾加密软件包含了表格数据加密、图纸加密、文档文件加密、内网文件加密流转、密级管控、电脑离线管理、文件外发管理、灵活的审批流程、工作模式切换、服务器白名单等功能。天锐绿盾加密系统全面覆盖Mac、Win…...
LeetCode - 394. 字符串解码
题目 394. 字符串解码 - 力扣(LeetCode) 思路 使用两个栈:一个存储重复次数,一个存储字符串 遍历输入字符串: 数字处理:遇到数字时,累积计算重复次数左括号处理:保存当前状态&a…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...
CocosCreator 之 JavaScript/TypeScript和Java的相互交互
引擎版本: 3.8.1 语言: JavaScript/TypeScript、C、Java 环境:Window 参考:Java原生反射机制 您好,我是鹤九日! 回顾 在上篇文章中:CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...
从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...
九天毕昇深度学习平台 | 如何安装库?
pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子: 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...
使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...
python爬虫——气象数据爬取
一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用: 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests:发送 …...
