哈希表
哈希表也叫散列表,是根据关键码值而直接进行访问的数据结构,通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。
- 举例:定义一个哈希表实现员工的增删改查
package com.hashTab;
import java.util.Scanner;
/*
* 使用哈希表完成员工的增删改查
*/
public class HashTabDemo2 {
public static void main(String[] args) {
// 创建哈希表
HashTab1 hashTab = new HashTab1(5);
// 写一个简单的菜单
String key = "";
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.println("add:添加雇员");
System.out.println("list:显示雇员");
System.out.println("find:查找雇员");
System.out.println("delete:删除雇员");
System.out.println("update:修改雇员信息");
System.out.println("exit:退出");
key = scanner.next();
switch (key) {
case "add":
System.out.println("请输入用户id");
int id = scanner.nextInt();
System.out.println("请输入名字");
String name = scanner.next();
Employe emp = new Employe(id, name);
hashTab.add(emp);
break;
case "list":
hashTab.list();
break;
case "find":
System.out.println("请输入要查找的id");
int findId = scanner.nextInt();
hashTab.findById(findId);
break;
case "delete":
System.out.println("请输入雇员编号");
int deleteId = scanner.nextInt();
hashTab.deleteByID(deleteId);
break;
case "update":
System.out.println("请输入雇员编号");
int updateId = scanner.nextInt();
System.out.println("请输入雇员姓名");
String updateName = scanner.next();
hashTab.updateById(new Employe(updateId, updateName));
break;
case "exit":
scanner.close();
System.exit(0);
break;
default:
break;
}
}
}
}
//定义哈希表
class HashTab1 {
private EmployeLinkedList[] empLinkedListArray;
private int size;// 哈希表中链表的个数
public HashTab1(int size) {
this.size = size;
// 初始化链表数组
empLinkedListArray = new EmployeLinkedList[size];
// 数组中的每个链表也要创建,否则会报空指针
for (int i = 0; i < empLinkedListArray.length; i++) {
empLinkedListArray[i] = new EmployeLinkedList();
}
}
// 按取模的方式创建散列函数
public int hashFun(int id) {
return id % size;
}
// 添加员工
public void add(Employe emp) {
int i = hashFun(emp.getId());
empLinkedListArray[i].addById(emp);
}
// 遍历哈希表
public void list() {
for (int i = 0; i < empLinkedListArray.length; i++) {
empLinkedListArray[i].list(i);
}
}
// 根据id查找员工
public void findById(int id) {
int i = hashFun(id);
Employe employe = empLinkedListArray[i].findById(id);
if (employe == null) {
System.out.printf("没有找到编号为%d的员工\n", id);
} else {
System.out.printf("编号为%d的员工姓名是:%s\n", id, employe.getName());
}
}
// 根据id删除员工
public void deleteByID(int id) {
int i = hashFun(id);
empLinkedListArray[i].deleteById(id, i);
}
// 根据id修改员工信息
public void updateById(Employe emp) {
int i = hashFun(emp.getId());
empLinkedListArray[i].updateById(emp, i);
}
}
//定义链表
class EmployeLinkedList {
private Employe head;// 头节点
// 按id顺序添加员工
public void addById(Employe emp) {
if (head == null) {// 第一次添加员工
head = emp;
return;
}
// 如果不是第一次添加,就先找到添加位置
Employe temp = head;
if (head.getId() > emp.getId()) {
head = emp;
head.setNext(temp);
return;
}
boolean flag = false;
while (true) {
if (temp.getNext() == null) {// 如果遍历到最后,还没找到,就在最后添加就行
break;
}
if (temp.getNext().getId() > emp.getId()) {// 如果temp的下一个节点的id大于要插入的id,那就在temp后面添加
flag = true;
break;
}
temp = temp.getNext();
}
if (flag) {
emp.setNext(temp.getNext());
temp.setNext(emp);
} else {
temp.setNext(emp);
}
}
// 遍历链表
public void list(int i) {
if (head == null) {
System.out.printf("第%d链表为空\n", i + 1);
return;
}
System.out.printf("第%d链表信息为:", i + 1);
Employe temp = head;
while (true) {
System.out.printf("=> id=%d,name=%s\t", temp.getId(), temp.getName());
if (temp.getNext() == null) {
break;
}
temp = temp.getNext();
}
System.out.println();
}
// 根据id查找雇员
public Employe findById(int id) {
if (head == null) {
return null;
}
Employe temp = head;
while (true) {
if (temp.getId() == id) {
break;
}
if (temp.getNext() == null) {
temp = null;
break;
}
temp = temp.getNext();
}
return temp;
}
// 根据id删除员工
public void deleteById(int id, int i) {
if (head == null) {
System.out.printf("第%d链表为空,没有编号为%d的员工\n", i + 1, id);
return;
}
Employe temp = head;
if (head.getId() == id) {
head = head.getNext();
System.out.printf("编号为%d的员工已删除\n", id);
return;
}
boolean flag = false;
while (true) {
if (temp.getNext() == null) {
break;
}
if (temp.getNext().getId() == id) {
flag = true;
break;
}
temp = temp.getNext();
}
if (flag) {
temp.setNext(temp.getNext().getNext());
System.out.printf("编号为%d的员工已删除\n", id);
} else {
System.out.printf("没有找到编号为%d的员工\n", id);
}
}
// 根据id修改员工信息
public void updateById(Employe emp, int i) {
if (head == null) {
System.out.printf("第%d链表为空,没有编号为%d的员工\n", i + 1, emp.getId());
return;
}
Employe temp = head;
if(head.getId()==emp.getId()) {
head.setName(emp.getName());
System.out.println("修改成功");
return;
}
boolean flag = false;
while (true) {
if (temp.getNext() == null) {
break;
}
if (temp.getId() == emp.getId()) {
flag = true;
break;
}
temp = temp.getNext();
}
if (flag) {
temp.setName(emp.getName());
System.out.println("修改成功");
} else {
System.out.printf("没有编号为%d的员工\n", emp.getId());
}
}
}
//定义员工类
class Employe {
private int id;// 员工编号
private String name;// 员工姓名
private Employe next;// 后指针
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Employe getNext() {
return next;
}
public void setNext(Employe next) {
this.next = next;
}
public Employe(int id, String name) {
super();
this.id = id;
this.name = name;
}
}