package com.hao.firstdemo.datastruct;
import java.util.Scanner;
/**
* @author haoxiansheng
* @Data 2020/4/30 7:00
*/
public class HashTableTest {
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("find: 查找雇员信息");
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();
Employee employee = new Employee(id, name);
hashTable.add(employee);
break;
case "list":
hashTable.list();
break;
case "find":
System.out.println("输入id");
int empId = scanner.nextInt();
hashTable.findById(empId);
break;
case "exit":
scanner.close();
System.out.println("退出");
break;
default:
break;
}
}
}
}
//雇员
class Employee{
public int id;
public String name;
public Employee next; //next 默认为空
public Employee(int id, String name) {
this.id = id;
this.name = name;
}
}
//创建HashTable 管理多条链表
class HashTable {
private EmpLinkedList [] empLinkedListArray;
private int size; //表示有多少条链表
/**
* 构造器初始化
* @param size
*/
public HashTable(int size) {
this.empLinkedListArray = new EmpLinkedList[size];
//是否可以用? 需要初始化EmpLinkedList
for (int i = 0; i < size; i++) {
//初始化EmpLinkedList 不然会报NPE
empLinkedListArray[i] = new EmpLinkedList();
}
this.size = size;
}
/**
* 添加雇员:根据员工id的到员工应该添加到那条链表
* @param emp
*/
public void add (Employee emp) {
int employeeListNo = hashFun(emp.id); //得到员工要添加到的链表
empLinkedListArray[employeeListNo].add(emp); //添加到对应的链表中
}
/**
* 遍历所有链表,遍历HashTable
*/
public void list () {
for (int i = 0; i < size; i++) {
empLinkedListArray[i].show(i);
}
}
/**
* 根据员工id和散列函数的到所在的列表
* @param id
* @return
*/
public void findById(int id) {
int employeeListNo = hashFun(id); //得到员工要添加到的链表
Employee employee = empLinkedListArray[employeeListNo].findEmpById(id);
if (employee != null) {
System.out.printf("在第%d条链表中找到了雇员id为:%d", employeeListNo, id);
} else {
System.out.println("没有找到雇员信息");
}
}
/**
* 编写一个散列函数:简单的取模法
*/
public int hashFun(int id) {
return id % size;
}
}
//创建 EmpLinkedList 表示链表
class EmpLinkedList {
//头指针指向第一个Emp,head 直接指向第一个Emp
private Employee head; //默认为null
/**
* 添加雇员到链表
* 说明:假定当添加雇员时,id是自增长的。既id的分配总是从小到达
* 因此我们将该雇员直接加入到本地链表的最后即可。
*/
public void add ( Employee emp ) {
//判断第一个是否为null
if (head == null) {
head = emp;
return;
}
Employee current = head; //借助辅助指针定位位置
while (true) {
if (current.next == null ) { //表示已到链表最后
break;
}
current = current.next; //向后移动
}
current.next = emp; //退出时将emp加入链表
}
/**
* 遍历雇员信息
*/
public void show(int number) {
if ( head == null) { //当前链表为null
System.out.println("第" + number + "链表为null");
return;
}
System.out.print("第" + number + "链表信息为");
Employee temp = head; //辅助变量
while (true) {
System.out.printf(" => id = %d name = %s\t\n",temp.id, temp.name);
if (temp.next == null) { //已经到链表的最后
break;
}
temp = temp.next; //后移
}
}
/**
* 根据id查找雇员
* @param id
* @return
*/
public Employee findEmpById(int id) {
if (head ==null) {
System.out.println("链表为null");
return null;
}
Employee temp = head; //辅助变量
while (true) {
if (temp.id == id) { //temp 就指向要查找的雇员
break;
}
if (temp.next == null) {
temp = null;
break;
}
temp = temp.next; //后移
}
return temp;
}
}