哈希表介绍

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

取模留余法

哈希地址:f(key) = key mod p (p<=m) m为哈希表表长。
这种方法是最常用的哈希函数构造方法。下面的代码中也使用了这种方法。

88714212f700a8f460b9bf0934d5684b.png

代码实现

import java.util.Scanner;

public class HashTabDemo {
    public static void main(String[] args) {
        //创建哈希表
        HashTab hashTab = new HashTab(7);
        //写一个简单的菜单
        String key = "";
        Scanner scanner = new Scanner(System.in);
        while (true) {
            System.out.println("add:  添加雇员");
            System.out.println("list: 显示雇员");
            System.out.println("find: 查找雇员");
            System.out.println("exit: 退出系统");

            key = scanner.next();
            switch (key) {
                case "add":
                    System.out.println("输入id");
                    int id = scanner.nextInt();
                    System.out.println("输入名字");
                    String name = scanner.next();
                    //创建 雇员
                    Emp emp = new Emp(id, name);
                    hashTab.add(emp);
                    break;
                case "list":
                    hashTab.showList();
                    break;
                case "find":
                    System.out.println("请输入要查找的id");
                    id = scanner.nextInt();
                    hashTab.findEmpById(id);
                    break;
                case "exit":
                    scanner.close();
                    System.exit(0);
                default:
                    break;
            }
        }
    }


}

//单个员工,链表节点
class Emp {
    public int id;
    public String name;
    public Emp next; //next 默认为 null

    public Emp(int id, String name) {
        super();
        this.id = id;
        this.name = name;
    }

    @Override
    public String toString() {
        return "Emp{" +
                "id=" + id +
                ", name='" + name +
                "'}";
    }
}

//管理一条链表,保存链表头部
class EmpLinkedList {
    private Emp head;

    //添加员工
    public void addEmp(Emp emp) {
        //如果头为空则直接使用传进来的新员工当头
        if (head == null) {
            head = emp;
            return;
        }
        Emp temp = head;
        while (temp.next != null) {
            temp = temp.next;
        }
        temp.next = emp;
    }

    public void showList() {
        if (head == null) {
            System.out.println("链表为空");
            return;
        }
        Emp temp = head;
        while (temp != null) {
            System.out.print(temp.toString()+"   ");
            temp = temp.next;
        }
    }

    public Emp findEmp(int id) {
        if (head == null) {
            System.out.println("链表为空");
            return null;
        }
        Emp temp = head;
        while (temp != null) {
            if (temp.id == id) {
                return temp;
            }
            temp = temp.next;
        }
        return null;
    }
}


//管理多条链表
class HashTab {
    EmpLinkedList[] empLinkedLists;
    private final int size;

    public HashTab(int size) {
        this.size = size;
        empLinkedLists = new EmpLinkedList[size];
    }

    public void add(Emp emp) {
        int hash = getHash(emp.id);
        if (empLinkedLists[hash] == null) {
            empLinkedLists[hash] = new EmpLinkedList();
        }
        empLinkedLists[hash].addEmp(emp);
    }

    public void showList() {
        for (EmpLinkedList empLinkedItem : empLinkedLists) {
            if (empLinkedItem == null)
                continue;
            empLinkedItem.showList();
        }
    }

    //根据输入的id,查找雇员
    public void findEmpById(int id) {
        int hash = getHash(id);
        if (empLinkedLists[hash] == null) {
            System.out.println("没找到");
            return;
        }
        Emp emp = empLinkedLists[hash].findEmp(id);
        System.out.println("find by id:" + id + "emp = " + emp.toString());
    }


    //散列函数,取模法
    public int getHash(int id) {
        return id % size;
    }
}
最后修改:2021 年 09 月 17 日 12 : 51 PM