Java实现哈希表(散列)

Java实现哈希表(散列)

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);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

毕竟尹稳健

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值