Java实现哈希表(散列)
- 1.简介
- 2.思路分析
- 3.图解
- 4.代码实现
1.简介
散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。
给定表M,存在函数f(key),对任意给定的关键字值key,代入函数后若能得到包含该关键字的记录在表中的地址,则称表M为哈希(Hash)表,函数f(key)为哈希(Hash) 函数。
- 向哈希表中插入一个关键字:哈希函数决定该关键字的对应值应该存放到表中的哪个区块,并将关键字放入区块中的链表最后一个节点后面
- 在哈希表中搜索一个关键字:使用相同的哈希函数从哈希表中查找对应的区块,并在特定的区块搜索该关键字对应的值
哈希表是一种将数组与链表相结合的数据结构
2.思路分析
- 需要一个节点类,一个链表,一个数组
- 数组中存入一条链表,链表中存一个一个节点
3.图解
数组+链表的形式
4.代码实现
/**
* 简单实现hash表
* @author 尹稳健~
* @version 1.0
* @time 2022/9/24
*/
public class HashTabExap {
public static void main(String[] args) {
HashTab hashTab = new HashTab(5);
Person person1 = new Person(1,"张三");
Person person2 = new Person(2,"李四");
Person person3 = new Person(3,"王五");
Person person4 = new Person(4,"赵六");
Person person5 = new Person(5,"何招财");
Person person6 = new Person(6,"冰有茂");
hashTab.add(person1);
hashTab.add(person2);
hashTab.add(person3);
hashTab.add(person4);
hashTab.add(person5);
hashTab.add(person6);
hashTab.traverse();
}
}
/** 节点 */
class Person{
int id;
String name;
Person next;
public Person(int id, String name) {
this.id = id;
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
class PersonLinkedList{
/** 头节点 */
private Person personHead = new Person(-1,"");
/**
* 向链表中添加节点
* @param person
*/
public void addPersonNode(Person person){
// 头节点的下一个节点如果为空那么就是空链表,直接添加到头节点的后面
Person tempPersonNode = personHead.next;
if (tempPersonNode == null){
personHead.next = person;
return;
}
// 遍历找到最后一个节点,将元素添加到最后一个节点后面
while (tempPersonNode.next != null){
tempPersonNode = tempPersonNode.next;
}
tempPersonNode.next = person;
}
/**
* 遍历链表中的所有节点元素
*/
public void traverse(){
Person tempPersonNode = personHead.next;
if (tempPersonNode == null){
System.out.println("链表为空!");
System.out.println("=========");
return;
}
while (tempPersonNode!=null){
System.out.println(tempPersonNode);
tempPersonNode = tempPersonNode.next;
}
System.out.println("=============");
}
/**
* 根据id搜索节点元素
* @param id
*/
public void findNodeById(int id){
if (personHead.next == null){
System.out.println("链表为空!");
return;
}
Person tempPersonNode = personHead.next;
while (tempPersonNode.next != null){
if (tempPersonNode.id == id){
System.out.println(tempPersonNode);
return;
}
tempPersonNode = tempPersonNode.next;
}
System.out.println("未找到!");
}
}
class HashTab{
private PersonLinkedList[] personLinkedLists;
private final int size;
public HashTab(int size) {
this.size = size;
personLinkedLists = new PersonLinkedList[size];
// 初始化链表,不然会报空指针异常
for (int i = 0; i < size; i++) {
personLinkedLists[i] = new PersonLinkedList();
}
}
/**
* 向数组元素中元素,再在链表中添加元素
* @param personNode
*/
public void add(Person personNode){
personLinkedLists[getHash(personNode.id)].addPersonNode(personNode);
}
/**
* 遍历每个数组中的链表元素
*/
public void traverse(){
for (int i = 0; i < size; i++) {
personLinkedLists[i].traverse();
}
}
/**
* 算出节点元素添加在数组的哪个位置,再添加在链表的最后
* @param id
* @return
*/
public int getHash(int id){
return id % size;
}
public void findNodeById(int id){
int hash = getHash(id);
personLinkedLists[hash].findNodeById(id);
}
}