哈希表(散列表)的代码实现及介绍

本文介绍了哈希表的基本概念,强调了其作为直接访问数据结构的优势,通过使用哈希函数加速查找速度。文章提供了哈希表的Java代码实现,采用数组加链表的方式,展示了添加、查找和删除学生记录的操作。并通过示例运行展示了哈希表的运作过程。此外,作者鼓励读者对代码的性能和潜在问题进行讨论和交流。
摘要由CSDN通过智能技术生成


一、哈希表(散列表)

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类问题,欢迎大家积极同我探讨交流学习

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值