散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。
1.哈希表管理员工
有一个公司,当有新的员工来报道时,要求将该员工的信息加入(id,姓名,性别, 年龄, 电话),当输入该员工的 id 时,要求查找到该员工的所有信息。
要求:
(1)不使用数据库,速度越快越好
(2)添加时,保证按照id从低到高插入
(3)使用链表来实现哈希表, 且链表不带表头
1)创建一个Emp类来表示一个员工信息
class Emp{
public int id;
public String name;
public Emp next; //next默认为空
public Emp(int id, String name) {
super();
this.id = id;
this.name = name;
}
}
2)创建链表来储存一个个的员工信息,及对链表的各种操作方法
//表示一个雇员信息链表
class EmpLinkList {
//头指针,执行第一个Emp,因此这个链表的head是直接指向第一个员工
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; //指针后移,直到最后
}
curEmp.next = emp; //指针到最后,将员工信息加入
}
//遍历链表的员工信息
public void showEmp(int no) {
if (head == null) {
System.out.println("第" + (no + 1) + "暂无员工信息!");
return;
}
System.out.println("第" + (no + 1) + "员工信息为:");
Emp curEmp = head;
while (true) {
System.out.print("id:" + curEmp.id + " 姓名:" + curEmp.name);
if (curEmp.next == null) {
break;
}
System.out.println();
curEmp = curEmp.next;
}
System.out.println();
}
//根据id查找员工
//如果查找到,则返回Emp,如果没有找到则返回null
public Emp findById(int id) {
//判断链表是否为空
if (head == null) {
return null;
}
//如果不为空,则一直向后找,直到找到该员工(需要辅助指针)
Emp curEmp = head;
while (curEmp != null) {
//若 == null 则说明遍历当前链表没有找到改 id 所对应的员工信息
if (curEmp.id == id) {
break;
}
curEmp = curEmp.next; //指针后移
}
return curEmp;
}
//删除链表员工信息
}
3)创建HashTable --> 使用数组来将链表分段保存
因为不能要通过哈希表来对链表进行操作,所以编写对链表操作的方法。
class HashTab{
private EmpLinkList[] empLinkListArray;
private int size;
//构造器
public HashTab(int size) {
this.size = size; //表示共有多少条链表
//初始化empLinkListArray,链表中共有几个数据
empLinkListArray = new EmpLinkList[size];
//!!!分别初始化数组中每一条链表
for (int i = 0; i < size; i++) {
empLinkListArray[i] = new EmpLinkList();
}
}
//添加员工
public void add(Emp emp){
//根据员工 id 得到员工应加入的链表(散列函数)
int empLinkListArrayNO = hashFun(emp.id);
//调用EmpLinkList类中的add方法,将员工加入
empLinkListArray[empLinkListArrayNO].add(emp);
}
//编写一个散列函数(取模法)
public int hashFun(int id){
return id % size;
}
//遍历所有链表
public void showList(){
if(empLinkListArray == null){
System.out.println("暂无员工信息!");
return;
}
for (int i = 0; i < size; i++) {
EmpLinkList empLinkList = empLinkListArray[i];
empLinkList.showEmp(i);
}
}
//根据输入id来查找员工信息
public void findById(int id){
int emempLinkListNo = hashFun(id);
Emp emp = empLinkListArray[emempLinkListNo].findById(id);
if(emp != null){
System.out.println("在第" + (emempLinkListNo+1) + "条链表找到员工 id = " + id + " name = " + emp.name);
}else {
System.out.println("暂无该员工信息!");
}
}
}