一、基本介绍
散列表(
Hash table
,也叫哈希表),是根据
关键码值(Key value)
而直接进行访问的数据结构。也就是说,它通
过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组
叫做
散列表
。

哈希表hashtable(key,value) 就是把Key通过一个固定的算法函数既所谓的哈希函数转换成一个整型数字,然后就将该数字对数组长度进行取余,取余结果就当作数组的下标,将value存储在以该数字为下标的数组空间里。
package com.zengwen.hashtab;
import java.util.Scanner;
public class HashTabDemo {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
StudentHashTab studentHashTab = new StudentHashTab(7);
while (true) {
System.out.println("add:添加学生");
System.out.println("list:遍历学生");
System.out.println("find:找到学生");
String next = scanner.next();
switch (next) {
case "add":
System.out.println("请输入学号:");
int stuNo = scanner.nextInt();
System.out.println("请输入姓名:");
String stuName = scanner.next();
Student student = new Student(stuNo, stuName);
studentHashTab.add(student);
break;
case "list":
studentHashTab.list();
break;
case "find":
System.out.println("请输入学号:");
stuNo = scanner.nextInt();
studentHashTab.findStudnentById(stuNo);
break;
default:
break;
}
}
}
}
//管理链表的哈希表
class StudentHashTab {
private StudentLinkedList[] studentHashTabArray;
private int size;
//构造器
public StudentHashTab(int size) {
this.size = size;
//初始化数组
studentHashTabArray = new StudentLinkedList[size];
//初始化数组元素链表
for (int i = 0; i < studentHashTabArray.length; i++) {
studentHashTabArray[i] = new StudentLinkedList();
}
}
//根据id寻找学生
public void findStudnentById(int id){
//计算出哈希码
int hashCode = hashFun(id);
Student student = studentHashTabArray[hashCode].findStudentById(id);
if (student == null){
System.out.println("未找到~~~");
return;
}
System.out.print("在第"+(hashCode+1)+"条链表中找到了他\t");
System.out.println(student);
}
//遍历
public void list() {
for (int i = 0; i < studentHashTabArray.length; i++) {
studentHashTabArray[i].list(i);
}
}
//添加
public void add(Student student) {
//计算出该学生对应的散列码
int hashNum = hashFun(student.stuNo);
//将其放到对应的链表中
studentHashTabArray[hashNum].add(student);
}
//散列函数
public int hashFun(int no) {
return no % size;
}
}
//管理Student节点的链表
class StudentLinkedList {
//头指针,用来指向第一个Student节点
private Student head;//默认值为null
//根据no找到该学生信息
public Student findStudentById(int id){
Student student = head;
while (true){
if (student == null){
return null;
}else if (student.stuNo == id){
return student;
}else {
student = student.next;
}
}
}
//遍历方法
public void list(int i) {
//判断当前链表是否为空
if (head == null) {
System.out.println("链表"+(i+1)+"为空~~~");
return;
}
//head不能动,创建一个临时变量用于遍历该链表所有的节点
Student curStudent = head;
//因为不知道循环次数,使用while循环
while (true) {
if (curStudent == null) {
break;
}else {
System.out.print("链表"+(i+1)+"信息~~~\t\t");
System.out.print("学号:" + curStudent.stuNo + "姓名:" + curStudent.stuName + "\t");
curStudent = curStudent.next;
}
}
System.out.println();
}
//添加方法
public void add(Student student) {
//判断当前链表是否为空
if (head == null) {
head = student;//head直接指向新节点
return;
}
//head不能动,创建一个临时变量用于遍历该链表所有的节点,
Student curStudent = head;
//因为不知道循环次数,使用while循环
while (true) {
if (curStudent.next != null) {//如果没有遍历到节点的最后,继续往后遍历
curStudent = curStudent.next;
} else {
curStudent.next = student;//将新的学生节点添加到链表最后
return;
}
}
}
}
//Student节点
class Student {
public int stuNo;//学号
public String stuName;//学生姓名
public Student next;
public Student(int stuNo, String stuName) {
this.stuNo = stuNo;
this.stuName = stuName;
}
@Override
public String toString() {
return "Student{" +
"stuNo=" + stuNo +
", stuName='" + stuName + '\'' +
'}';
}
}