一、哈希表(散列表)
1.解释
这里引入百度百科的解释:
- 散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。
- 也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。
- 给定表M,存在函数f(key),对任意给定的关键字值key,代入函数后若能得到包含该关键字的记录在表中的地址,则称表M为哈希(Hash)表,函数f(key)为哈希(Hash) 函数。
- 哈希表(散列表、HashTable)是根据key值进行直接访问的数据结构。也就是说,它通过把关键字映射到表中的某个位置,加快访问速度。这个映射函数叫做哈希函数或者散列函数或者哈希方法。
推荐一篇UP主的博客:具有更详细的介绍
哈希表
2.代码实现
- 哈希表的代码实现可以通过:
- 1.数组+链表(示例)
- 2.数组+树
引入代码
package com.lingo.hashTable;
/**
* 哈希表重中之重 由数组+链表组成
* 优点:可以利用数组的快速查询
* 利用链表的删除修改
*/
public class HashTable {
private int size;
private StudentList[] studentLists;
public HashTable(int size) {
this.size = size;
studentLists = new StudentList[size];
//非引用类型可以不去初始化
//引用类型需要初始化
for (int i = 0; i < size; i++) {
studentLists[i] = new StudentList();
}
}
/**
* 取模法获取下标
*
* @param id
* @return 返回学生链表所在的数组下标
*/
public int hashFunction(int id) {
return id % size;
}
public void add(Student student) {
int index = hashFunction(student.id);
studentLists[index].add(student);
}
public void findStudentById(int id) {
//核心代码 (找到在哪一条链表中进行查询【哈希函数/散列函数】)
int index = hashFunction(id);
Student student = studentLists[index].findStudentById(id);
if (student != null) {
System.out.println("该学生所在的链表下标:" + index + " ->id:" + student.id + " name:" + student.name);
} else {
System.out.println("未查询到该学生");
}
}
/**
* 删除
*
* @param id
* @return 成功返回 删除学生的姓名,失败返回null
*/
public String deleteStudentById(int id) {
int index = hashFunction(id);
// Student student = studentLists[index].findStudentById(id);
// if (student==null){
// return "null";
// }
return studentLists[index].deleteStudentById(id);
}
public void list() {
for (int i = 0; i < size; i++) {
studentLists[i].list(i);
}
}
public static void main(String[] args) {
HashTable hashTable = new HashTable(10);
hashTable.add(new Student(111, "林果"));
hashTable.add(new Student(11, "孙奇"));
hashTable.add(new Student(12, "张三"));
hashTable.add(new Student(13, "李四"));
hashTable.add(new Student(51, "赵六"));
hashTable.add(new Student(18, "王五"));
hashTable.list();
System.out.println("=======================");
hashTable.findStudentById(18);
// System.out.println("=======================");
System.out.println(hashTable.deleteStudentById(10));
// System.out.println(hashTable.deleteStudentById(18));
// System.out.println("=======================");
// hashTable.list();
System.out.println("=======================");
System.out.println(hashTable.deleteStudentById(18));
System.out.println("=======================");
hashTable.list();
}
}
class Student {
public int id;
public String name;
public Student next;
public Student(int id, String name) {
this.id = id;
this.name = name;
this.next = null;
}
}
class StudentList {
private Student head;
public StudentList() {
head = null;
}
/**
* 不设置虚拟头节点
*
* @param student
*/
public void add(Student student) {
//如果head为空
if (head == null) {
head = student;
return;
}
//head不为空
Student currentStu = head;
while (currentStu.next != null) {
currentStu = currentStu.next;
}
currentStu.next = student;
}
/**
* 学生链表的遍历
*/
public void list(int index) {
System.out.print("链表下标:" + index);
if (head == null) {
System.out.println(" ->null");
return;
}
Student currentStu = head;
while (currentStu != null) {
System.out.print(" ->id:" + currentStu.id + " name:" + currentStu.name);
currentStu = currentStu.next;
}
System.out.println();
}
public Student findStudentById(int id) {
Student currentStudent = head;
while (currentStudent != null) {
if (currentStudent.id == id) {
return currentStudent;
}
currentStudent = currentStudent.next;
}
return null;
}
public String deleteStudentById(int id) {
String delName = null;
//链表的删除
if (head == null) {
return delName;
}
//1.删除头节点
if (head.id == id) {
delName = head.name;
head = head.next;
return delName;
}
//2.删除任意节点
Student prevStudent = head;
while (prevStudent.next != null) {
if (prevStudent.next.id == id) {
Student currentStu = prevStudent.next;
delName = currentStu.name;
prevStudent.next = currentStu.next;
currentStu.next = null;
break;
}
prevStudent = prevStudent.next;
}
return delName;
}
}
输出结果:
链表下标:0 ->null
链表下标:1 ->id:111 name:林果 ->id:11 name:孙奇 ->id:51 name:赵六
链表下标:2 ->id:12 name:张三
链表下标:3 ->id:13 name:李四
链表下标:4 ->null
链表下标:5 ->null
链表下标:6 ->null
链表下标:7 ->null
链表下标:8 ->id:18 name:王五
链表下标:9 ->null
======================
该学生所在的链表下标:8 ->id:18 name:王五
======================
王五
=======================
链表下标:0 ->null
链表下标:1 ->id:111 name:林果 ->id:11 name:孙奇 ->id:51 name:赵六
链表下标:2 ->id:12 name:张三
链表下标:3 ->id:13 name:李四
链表下标:4 ->null
链表下标:5 ->null
链表下标:6 ->null
链表下标:7 ->null
链表下标:8 ->null
链表下标:9 ->null
二、探讨学习
当然,不排除博客中所涉及的代码可能仍存在性能问题或BUG类问题,欢迎大家积极同我探讨交流学习