这是我参与8月更文挑战的第22天,活动详情查看:8月更文挑战”
哈希表
1. 哈希表基本介绍
散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。
2. 哈希表原理
思路分析:
比如使用添加一个学生到校园系统中去,输入学生学号可以查找出该学生所有信息。
要求:
1、 添加学生编号时按照从低到高的顺序
2、 使用链表来实现哈希表,该链表不带表头
3. 哈希表应用案例
student
/**
* author:韩国庆
* date:2021/3/20 15:55
* version:1.0
*/
public class Student {
public int id;
public String name;
public Student next;
public Student(int id, String name) {
this.id = id;
this.name = name;
}
}
Student L inked L ist
/**
* author:韩国庆
* date:2021/3/20 15:58
* version:1.0
*/
public class StudentLinkedList {
private Student head;
public void add(Student newStudent){
/**
* 如果添加时是第一个学生对象。则使用一个指针,帮助找到最后一个
*/
if (head ==null){
head = newStudent;
return;
}
/**
* 如果添加时不是第一个学生对象
*/
Student tempStudent = head;
while (true){
/**
*
*/
if (tempStudent.next==null){
break;
}
/**
* 否则后移一个
*/
tempStudent = tempStudent.next;
}
/**
* 循环结束后,将新的学生加入到链表中
*/
tempStudent.next = newStudent;
}
/**
* 遍历链表的学生信息
*/
public void list(int no){
/**
* 说明为null时
*/
if (head == null){
System.out.println("第"+(no+1)+"链表为空");
return;
}
System.out.println("第"+(no+1)+"链表信息为");
Student tempStudent = head;
while (true){
System.out.printf("id=%d name=%s\t",tempStudent.id,tempStudent.name);
/**
* 说明已经是最后一个结点了
*/
if (tempStudent.next == null){
break;
}
tempStudent = tempStudent.next;
}
System.out.println();
}
public Student findByStudentId(int id){
if (head == null){
System.out.println("链表为空");
return null;
}
/**
* 辅助指针
*/
Student pointStudent = head;
while (true){
/**
* 找到id值
*/
if (pointStudent.id == id){
break;
}
/**
* 说明当前链表没有该学员
*/
if (pointStudent.next == null){
pointStudent = null;
break;
}
pointStudent = pointStudent.next;
}
return pointStudent;
}
}
Hash T able
/**
* author:韩国庆
* date:2021/3/20 16:58
* version:1.0
*/
public class HashTable {
private StudentLinkedList[] studentLinkedLists;
private int size;
public HashTable(int size){
this.size = size;
studentLinkedLists = new StudentLinkedList[size];
for (int i=0;i<size;i++){
studentLinkedLists[i] = new StudentLinkedList();
}
}
/**
* 添加学员
*/
public void add(Student student){
/**
* 根据学员的id,得到该学员应当添加到哪一条链表上
*/
int linkedListNode = hashValue(student.id);
/**
* 讲学生对象添加到链表中去
*/
studentLinkedLists[linkedListNode].add(student);
}
/**
* 遍历所有的链表
*/
public void list(){
for (int i=0;i<size;i++){
studentLinkedLists[i].list(i);
}
}
/**
* 根据输入的编号查询学员
*/
public void findByStudentId(int id){
int linkedListNode = hashValue(id);
Student students = studentLinkedLists[linkedListNode].findByStudentId(id);
/**
* 找到指定的对象
*/
if (students !=null){
System.out.printf("在第%d条链表中找到学员, 编号是:%d\n",(linkedListNode+1),id);
}else {
System.out.println("整个哈希表中没有找到该学员");
}
}
/**
*编写一个散列函数,使用一个简单取模办法
*/
public int hashValue(int id){
return id%size;
}
}
Test
/**
* author:韩国庆
* date:2021/3/20 15:55
* version:1.0
*/
public class Test {
public static void main(String[] args) {
HashTable hashTable = new HashTable(10);
Scanner scanner = new Scanner(System.in);
while (true){
System.out.println("add:添加学员");
System.out.println("list:显示学员");
System.out.println("find:查找学员");
System.out.println("exit:退出系统");
String next = scanner.next();
switch (next){
case "add":
System.out.println("请输入id");
int id = scanner.nextInt();
System.out.println("请输入名字");
String name = scanner.next();
Student student = new Student(id,name);
hashTable.add(student);
break;
case "list":
hashTable.list();
break;
case "find":
System.out.println("请输入要查找的id");
id = scanner.nextInt();
hashTable.findByStudentId(id);
break;
case "exit":
scanner.close();
System.exit(0);
break;
default:
break;
}
}
}
}