🧡数据结构与算法🧡从零到有系列《十》哈希表

242 阅读3分钟

这是我参与8月更文挑战的第22天,活动详情查看:8月更文挑战

哈希表

1. 哈希表基本介绍

散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。  

2. 哈希表原理

image.png

思路分析:

比如使用添加一个学生到校园系统中去,输入学生学号可以查找出该学生所有信息。

要求:

1、 添加学生编号时按照从低到高的顺序

2、 使用链表来实现哈希表,该链表不带表头

image.png

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;

 

            }

 

        }

    }

}