哈希表的基本介绍
散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。
(哈希表的底层是数组)
实现哈希表的两种方法:
1、数组+链表
2、数组+红黑二叉树
使用哈希表管理雇员信息
题目:有一个公司,当有新的员工来报道时,要求将该员工的信息加入(id、姓名,性别,电话),当输入该员工的id时,要求查找到该员工的所有信息.
要求:
不使用数据库,速度越快越好
添加时,保证按照id从低到高插入
使用链表来实现哈希表, 该链表不带表头
思路分析:
添加雇员信息
创建一个节点类存储雇员的信息(id,name,sex,phone)
创建一个定长数组为哈希表,哈希表的每个数组元素储存一条链表头节点
根据散列函数将要添加的雇员id进行散列(比如:散列函数构造采用简单的取模法:H(k)=id % size 假如id=1001 数组长度为7则取余后的key为0 对应的数组下标为0)
根据id散列后的key值将对应id的雇员节点链接到对应的数组下标下的链表后面
查找对应id的雇员信息:
根据id散列得到key值
到key值对应的数组下标的链表中进行查询
代码实现:
package HashCode;
import java.util.Scanner;
public class HashCode {
public static void main(String[] args) {
//创建一个HashTab对象
HashTab hashTab = new HashTab(7);
//写一个简单的菜单
int n;
Scanner scanner = new Scanner(System.in);
while(true) {
System.out.println("1: 添加雇员");
System.out.println("2: 显示雇员");
System.out.println("3: 查找雇员");
System.out.println("4: 退出系统");
n = scanner.nextInt();
switch (n) {
case 1:
System.out.println("输入id");
int id = scanner.nextInt();
System.out.println("输入名字");
String name = scanner.next();
System.out.println("输入性别");
String sex = scanner.next();
System.out.println("输入电话");
String phone = scanner.next();
//创建 雇员
Emp emp = new Emp(id, name,sex,phone);
hashTab.addemp(emp);
break;
case 2:
hashTab.hashList();
break;
case 3:
System.out.println("请输入要查找的id");
id = scanner.nextInt();
hashTab.hashfind(id);
break;
case 4:
scanner.close();
System.exit(0);
default:
break;
}
}
}
}
//添加雇员
class Emp{
public int id;
public String name;
public String sex;
public String phone;
public Emp next;
public Emp(int id,String name,String sex,String phone){
super();
this.id=id;
this.name=name;
this.phone=phone;
this.sex=sex;
}
}
//创建员工链表,添加员工信息
class empLinkList{
public Emp head;//头节点,默认为空
//向链表中添加员工
public void add(Emp emp){
//如果是第一个员工
if(head==null){
head=emp;
return;
}
//如果不是第一个员工,则添加辅助指针,帮助定位到链表最后
Emp curemp=head.next;//辅助指针
while(true){
//如果已经到链表最后位置,则停止
if(curemp==null){
break;
}
//如果未到最后位置,则指针继续后移
curemp=curemp.next;
}
//退出时,直接将em加入链表
curemp=emp;
}
//遍历链表雇员信息
public void show(int no){
if(head==null){
System.out.println("第" + (no+1) +"链表为空");
return;
}
System.out.print("第" + (no+1) +"链表员工的信息为:");
Emp curemp=head;
while(true){
System.out.print("员工id:"+curemp.id+" 员工姓名:"+curemp.name);
if(curemp.next==null){
break;
}
curemp=curemp.next;
}
System.out.println();
}
//通过id寻找员工信息
public Emp findempId(int id){
if(head==null){
System.out.printf("链表为空");
return null;
}
//如果链表不为空,则添加辅助指针
Emp curemp=head;
while(true){
//如果找到,要查找指针指向curemp.id
if(curemp.id==id){
break;
}
//如果未找到,则指针继续后移
curemp=curemp.next;
}
//找到指定id对应的员工,返回员工信息
return curemp;
}
}
//创建HashTab 管理多条链表
class HashTab{
//定义一个哈希数组
private empLinkList[] empLinkListArray;
//获取数组长度
public int size;
public HashTab(int size){
super();
this.size=size;
empLinkListArray=new empLinkList[size];
for(int i=0;i<size;i++){
empLinkListArray[i]=new empLinkList();
}
}
//编写散列函数,使用简单取模法
public int hashtab(int id){
return id%size;
}
//根据员工id将对应员工添加到链表
public void addemp(Emp emp){
int empno=hashtab(emp.id);
empLinkListArray[empno].add(emp);
}
//遍历员工链表
public void hashList(){
for(int i=0;i<size;i++){
empLinkListArray[i].show(i);
}
}
//根据输入的id,查找雇员
public void hashfind(int id){
int empno=hashtab(id);
Emp emp=empLinkListArray[empno].findempId(id);
if(emp==null){
System.out.printf("没有此员工信息");
return;
}else{
System.out.printf("该员工信息为:");
System.out.println("员工id: "+emp.id+" 性别:"+emp.sex+" 姓名:"+emp.name+" 电话:"+emp.phone);
}
}
}
测试
"C:\Program Files\Java\jdk1.8.0_191\bin\java.exe" "-javaagent:D:\IDEA\IntelliJ IDEA Community Edition 2020.2.3\lib\idea_rt.jar=63600:D:\IDEA\IntelliJ IDEA Community Edition 2020.2.3\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_191\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\rt.jar;D:\java-idea\out\production\java-idea" HashCode.HashCode
1: 添加雇员
2: 显示雇员
3: 查找雇员
4: 退出系统
1
输入id
0
输入名字
李玉
输入性别
女
输入电话
17789560431
1: 添加雇员
2: 显示雇员
3: 查找雇员
4: 退出系统
1
输入id
1
输入名字
张欢
输入性别
女
输入电话
17895567434
1: 添加雇员
2: 显示雇员
3: 查找雇员
4: 退出系统
1
输入id
2
输入名字
王军
输入性别
男
输入电话
1789594327
1: 添加雇员
2: 显示雇员
3: 查找雇员
4: 退出系统
1
输入id
3
输入名字
肖玲
输入性别
女
输入电话
1909455792334
1: 添加雇员
2: 显示雇员
3: 查找雇员
4: 退出系统
1
输入id
4
输入名字
窦浩
输入性别
男
输入电话
1894567321
1: 添加雇员
2: 显示雇员
3: 查找雇员
4: 退出系统
1
输入id
5
输入名字
刘义
输入性别
男
输入电话
1795454765738
1: 添加雇员
2: 显示雇员
3: 查找雇员
4: 退出系统
2
第1链表员工的信息为:0李玉
第2链表员工的信息为:1张欢
第3链表员工的信息为:2王军
第4链表员工的信息为:3肖玲
第5链表员工的信息为:4窦浩
第6链表员工的信息为:5刘义
第7链表为空
1: 添加雇员
2: 显示雇员
3: 查找雇员
4: 退出系统
3
请输入要查找的id
4
该员工信息为:员工id 4 性别男 姓名窦浩 电话1894567321
1: 添加雇员
2: 显示雇员
3: 查找雇员
4: 退出系统
4
Process finished with exit code 0