数据结构 —— 哈希表

十一、哈希表(散列)

应用场景

有一个公司,当右新的员工来报道时,要求将该员工的信息加入(id,性别,年龄,住址…),当输入该员工id时,要求查到该员工索引信息

要求:不适用数据库,尽量节省内存,速度越快越好

基本介绍

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

image-20201102173455937

实现缓存层

image-20201103170713180

定义哈希表可以自己实现缓存层:

  • 数组+链表
  • 数组+二叉树

11.1 使用哈希表管理雇员信息

需求

有一个公司,当右新的员工来报道时,要求将该员工的信息加入(id,性别,年龄,住址…),当输入该员工id时,要求查到该员工索引信息

要求:不适用数据库,尽量节省内存,速度越快越好

思路分析

image-20201103171541293

  1. 创建员工类,实现存储员工信息
  2. 创建链表头指针指向第一个员工
  3. 创建哈希表,建立数组属性,存储这些链表;创建散列函数,决定id对应的链表(数组的元素)
  4. 通过哈希表实现增删改查

代码实现

package com.why.a;

/**
 * @Description TODO 哈希表
 * @Author why
 * @Date 2020/11/3 18:00
 * Version 1.0
 **/
public class HashTable {
    public static void main(String[] args) {
        hashTable hashTable = new hashTable(3);
        Employee e1 = new Employee(1,"why","男",14,"兰州");
        Employee e2 = new Employee(2,"why","男",14,"兰州");
        hashTable.add(e1);
        hashTable.add(e2);
        hashTable.list();
    }
}

/**
 * 管理多条链表
 */
class hashTable{
    int size;
    private HashLinkedList[] hashLinkedListsArr;

    public hashTable(int size) {
        this.size = size;
        hashLinkedListsArr = new HashLinkedList[size];
        //不要忘记分别初始化每一条链表
        for (int i = 0; i < size; i++) {
            hashLinkedListsArr[i] = new HashLinkedList();
        }
    }

    /**
     * 添加雇员
     * @param node
     */
    public void add(Employee node){
        //根据员工id,得到该员工应该添加到哪条链表
        int empLinkedListNo = hasFun(node.getId());
        //将employee添加到对应的链表中
        hashLinkedListsArr[empLinkedListNo].insert(node);
    }

    /**
     * 遍历hash表
     */
    public void list(){
        for (int i = 0; i < hashLinkedListsArr.length; i++) {
            hashLinkedListsArr[i].show();
        }
    }
    /**
     * 编写散列函数,使用简单的取模法
     * @param id
     * @return
     */
    public int hasFun(int id){
        return id % size;
    }
}

class HashLinkedList {
    //头指针
    private Employee head = new Employee();

    /**
     * 添加功能
     */
    public void insert(Employee employee){
        Employee temp = head;
        while (true){
            if (temp == null){
                break;
            }
            temp = temp.getNext();
        }
        temp.setNext(employee);
    }
    /**
     * 删除
     * @param id
     */
    public void delete(int id){
        if (head == null){
            System.out.println("空");
        }
        Employee temp = head;
        while (true){
            if (temp.getId() == id){
                temp.setNext(temp.getNext());
                break;
            }
            temp = temp.getNext();
        }
    }
    /**
     * 更新
     * @param employee
     */
    public void update(Employee employee){
        if (head == null){
            System.out.println("空");
        }
        Employee temp = head;
        while (true){
            if (temp.getId() == employee.getId()){
                temp.setId(employee.getId());
                temp.setName(employee.getName());
                temp.setAddress(employee.getAddress());
                temp.setAge(employee.getAge());
                temp.setGender(employee.getGender());
                break;
            }
            temp = temp.getNext();
        }
    }

    /**
     * 根据id查询一条记录
     * @param id
     * @return
     */
    public Employee findById(int id){
        if (head.getNext() == null){
            System.out.println("空");
        }
        Employee temp = head;
        while (true){
            if (temp.getId() == id){
                Employee employee = temp;
                return employee;
            }
            temp = temp.getNext();
        }
    }
    /**
     * 遍历显示
     */
    public void show(){
        //判空
        if (head == null){
            System.out.println("空");
        }
        Employee temp = head;
        while (true){
            if (temp == null){
                break;
            }
            //输出节点信息
            System.out.println(temp);
            temp = temp.getNext();
        }
    }
}


class Employee {
    private int id;
    private String name;
    private String gender;
    private int age;
    private String address;
    private Employee next;

    public Employee() {
    }

    public Employee(int id, String name, String gender, int age, String address) {
        this.id = id;
        this.name = name;
        this.gender = gender;
        this.age = age;
        this.address = address;
    }

    public Employee getNext() {
        return next;
    }

    public void setNext(Employee next) {
        this.next = next;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                ", age=" + age +
                ", address='" + address + '\'' +
                '}';
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值