哈希表
基本介绍
散列表(Hash table,也叫哈希表),是根据关键码值(Key Value)而直接进行访问的数据结构
也就是说,它通过把关键码值映射到表中的一个位置来访问记录,以加快查找的速度。
这个映射函数叫做三列函数,存放记录的数组叫做散列表。
链表数组:数组+链表
哈希表管理雇员系统
要求
有一个公司,当有新的员工来报道时,要求将该员工的信息加入
(id,性别,年龄,名字,住址.),当输入该员工的id时,要求查找到该员工的所有信息
要求
不使用数据库,速度越快越好=>哈希表(散)
分析图解
使用哈希表来管理雇员信息
代码
package H哈希表;
import com.sun.org.apache.xpath.internal.SourceTree;
import java.util.List;
import java.util.Scanner;
/**
* @Author Zhou jian
* @Date 2020 ${month} 2020/1/5 0005 23:16
*/
public class HashTableDemo {
public static void main(String[] args) {
//创建哈希表
HashTable hashTable = new HashTable(7);
//写一个简单菜单测试
String key = "";
Scanner scanner = new Scanner(System.in);
while(true){
System.out.println("add:添加雇员");
System.out.println("list:显示用户");
System.out.println("exit:tuichgu");
System.out.println("find:查找雇员");
key=scanner.next();
switch(key){
case "add":
System.out.println("输入id");
int id = scanner.nextInt();
System.out.println("输入名字");
String name = scanner.next();
//创建雇员
Emp emp = new Emp(id,name);
hashTable.add(emp);
break;
case "list":
hashTable.list();
break;
case "exit":
scanner.close();
System.exit(0);
case "find":
System.out.println("输入查找id");
int findId = scanner.nextInt();
hashTable.findById(findId);
break;
default:
break;
}
}
}
}
//表示雇员
class Emp{
int id;
String name;
Emp next;
public Emp(int id, String name) {
this.id = id;
this.name = name;
}
@Override
public String toString() {
return "Emp{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
//创建EmployeLinkeList,表示链表‘
class EmpLinkedList{
//头指针,指向第一个Emp,因此我们这个链表的head是有效的是直接指向第一个Emp
private Emp head; //默认为空
//添加雇员到链表
//假定添加雇员到链表的最后,
//id是自增的,即id的分配式从小打到的
//因此我们将雇员直接加入到本链表的最后即可
public void add(Emp emp){
//如果添加第一个雇员
if(head==null){
head = emp;
return;
}else{ //链表中已经存在元素
Emp temp = head;//定义辅助指针,帮助定位到最后
while(temp.next!=null){
temp = temp.next;
}
temp.next = emp;
}
}
//遍历链表
public void list(int no){
if(head==null){
System.out.println("第"+no+"条链表为空");
return;
}else{
System.out.print("第"+no+"条链表信息为:");
Emp temp = head;
while(temp!=null){
System.out.print(temp);
temp=temp.next;//后移遍历
}
System.out.println();
}
}
//根据id查找雇员
//
public Emp findEmpById(int id){
boolean flag = false;
//判断链表是否为空
if(head==null){
System.out.println("链表为空");
return null;
}else{
Emp temp = head;
while(temp!=null){
if(temp.id==id){
flag = true;
break;
}
temp = temp.next;
}
if(flag){
return temp;
}else{
return null;
}
}
}
}
//创建HashTable,管理多条链表
class HashTable{
private int size; //表示公有多少条链表
private EmpLinkedList[] empLinkedListArray;//数组里面放链表
//构造器
public HashTable(int size){
this.size = size;
//初始化empLinkedListArray
empLinkedListArray = new EmpLinkedList[size];
//不要忘了分别初始化每一条链表
for(int i=0;i<size;i++){
empLinkedListArray[i] = new EmpLinkedList();
}
}
//添加雇员
public void add(Emp emp){
//根据员工的id,得到该员工应当加入到哪条链表
int empLinkedListNo = hashFun(emp.id);
//将employee添加到对应的链表中
empLinkedListArray[empLinkedListNo].add(emp);
}
//遍历所有的链表
public void list(){
//遍历哈希表,遍历每条链表
for(int i=0;i<size;i++){
empLinkedListArray[i].list(i);
}
}
//根据输入id,查找雇员
public void findById(int id){
//使用散列函数确定到哪条链表查找
int empLinkeListNo = hashFun(id);
Emp emp = empLinkedListArray[empLinkeListNo].findEmpById(id);
if(emp==null){
System.out.println("没有找到");
}else{
System.out.println("在第"+empLinkeListNo+"条链表找到改数据"+emp);
}
}
//编写一个散列函数,使用一个简单的取模法
private int hashFun(int id){
return id%size;
}
}