实现了crud功能,其中delete功能是自己独立写的
package com.atguigu.hashtable;
import java.util.Scanner;
/**
* 哈希表
* 谷歌面试题
*
* @author Dxkstart
* @create 2021-10-15-19:27
*/
public class HashTableDemo {
public static void main(String[] args) {
//创建哈希表
HashTable hashTable = new HashTable(7);
//写一个简单的菜单
Scanner scanner = new Scanner(System.in);
String key;
L:
while (true) {
System.out.println("~~~欢迎使用HashTable~~~");
System.out.println("1.添加员工信息");
System.out.println("2.删除员工信息");
System.out.println("3.显示所有员工信息");
System.out.println("4.根据id号查找员工信息");
System.out.println("5.退出程序");
key = scanner.next();
switch (key) {
case "1":
System.out.println("请输员工信息");
System.out.println("id:");
int id = scanner.nextInt();
System.out.println("名字:");
String name = scanner.next();
hashTable.add(new Emp(id, name));
break;
case "2":
System.out.println("请输要删除的员工的id");
id = scanner.nextInt();
hashTable.delete(id);
break;
case "3":
hashTable.list();
break;
case "4":
System.out.println("请输要查找的员工的id");
id = scanner.nextInt();
hashTable.findEmpById(id);
break;
case "5":
scanner.close();
break L;
}
}
}
}
//创建HashTable 管理多条链表
class HashTable {
private EmpLinkedList[] empLinkedListsArray;
private int size;//表示有多少条链表
//构造器
public HashTable(int size) {
this.size = size;
//初始化empLinkedListsArray
empLinkedListsArray = new EmpLinkedList[size];
//?小心这里有坑,这是不要忘了分别初始化每一条链表!!!
for (int i = 0; i < size; i++) {
empLinkedListsArray[i] = new EmpLinkedList();
}
}
//添加员工
public void add(Emp emp) {
//根据员工的id,得到该员工应当添加到哪条链表
int empLinkedListNo = hashFun(emp.id);
//将emp添加到对应的链表中
empLinkedListsArray[empLinkedListNo].add(emp);
}
//遍历员工(遍历所有的链表,即哈希表)
public void list() {
for (int i = 0; i < size; i++) {
empLinkedListsArray[i].list(i);
}
}
//根据输入的id,查找员工信息
public void findEmpById(int id) {
//根据员工的id,得到该员工应当添加到哪条链表
int empLinkedListNo = hashFun(id);
Emp emp = empLinkedListsArray[empLinkedListNo].findEmpById(id);
if (emp != null) {
System.out.printf("在第%d条链表中找到员工 id = %d , 名字:%s \n", (empLinkedListNo + 1), id, emp.name);
} else {
System.out.println("没有找到该员工信息");
}
}
//删除员工
public void delete(int id) {
//根据员工的id,得到该员工在哪条链表
int empLinkedListNo = hashFun(id);
//删除对应的员工
empLinkedListsArray[empLinkedListNo].delete(id);
}
//编写一个散列函数,使用一个简单的取模法
//说明:
//这个HashTable中是一个数组,每个数组有一条链表,
//加入员工时,要确定这个员工加入到哪条链表中去
//即:要确定的是数组的角标
public int hashFun(int id) {
return id % size;
}
}
//表示一个雇员
class Emp {
public int id;
public String name;
public Emp next;//next 默认为null
public Emp(int id, String name) {
this.id = id;
this.name = name;
}
}
//创建EmpLinkedList,表示链表
class EmpLinkedList {
//头指针,指向第一个Emp,因此我们这个链表的head 是直接指向第一个Emp
private Emp head;//默认null
//添加员工到链表
//说明:
//1.假定,当添加雇员时,id 是自增长的,即id的分配总是从小到大
// 因此我们将该雇员直接加入到本链表的最后即可
public void add(Emp emp) {
//如果是添加第一个员工
if (head == null) {
head = emp;
return;
}
//如果不是第一个员工,则使用一个辅助的指针,帮助定位到最后
Emp curEmp = head;
while (true) {
if (curEmp.next == null) {//说明到链表的最后
break;
}
curEmp = curEmp.next;//往后移
}
//退出循环时,即指针指向了链表的最后
//将emp(员工信息),连接到链表尾部
curEmp.next = emp;
}
//遍历链表信息
public void list(int no) {
if (head == null) {//说明链表为空
System.out.println("第" + (no + 1) + "条链表为空!");
return;
}
System.out.println("第" + (no + 1) + "条链表的信息为:");
Emp curEmp = head;//辅助指针
while (true) {
System.out.printf(" => id = %d, name = %s \n", curEmp.id, curEmp.name);
if (curEmp.next == null) {//说明到链表的最后
break;
}
curEmp = curEmp.next;//后移遍历
}
}
//根据id,查找员工信息
//如果找到,就返回Emp,如果没有找到,就返回null
public Emp findEmpById(int id) {
//判断链表是否为空
if (head == null) {
System.out.println("链表为空");
return null;
}
//辅助指针
Emp curEmp = head;
while (true) {
if (curEmp.id == id) {
break;//这是curEmp就指向要查找的员工
}
//退出循环的条件
if (curEmp.next == null) {//说明当前链表没有找到该雇员
curEmp = null;
break;
}
curEmp = curEmp.next;//后移指针
}
return curEmp;
}
//删除链表信息(自己写的)
public void delete(int id) {
if (head == null) {//说明链表为空
System.out.println("当前链表为空");
return;
}
Emp curEmp = head;//辅助指针
if (curEmp.next == null && curEmp.id == id) {//只有一个员工
head = null;
System.out.println("删除成功1");
return;
}
while (true) {//将辅助指针指向要删除的节点的上一个节点
if (curEmp.next == null) {//说明到链表的最后
System.out.println("没有此员工信息");
return;
}
if (curEmp.next.id == id) {
break;
}
curEmp = curEmp.next;//后移遍历
}
if (curEmp.next.next == null) {//如果此节点是链表上的最后一个节点
curEmp.next = null;
System.out.println("删除成功end");
return;
}
curEmp.next = curEmp.next.next;
System.out.println("删除成功");
}
}