数据结构与算法—哈希表

哈希表

文章目录

  • 哈希表
    • 1. 问题引出
    • 2. 基本介绍
    • 3. 应用实例

1. 问题引出

  看一个实际需求,google公司的一个上机题:有一个公司,当有新的员工来报道时,要求将该员工的信息加入(id,性别,年龄等),当输入该员工的id时,要求查到该员工的所有信息。要求: 不使用数据库,尽量节省内存,速度越快越好=>哈希表(散列)。

2. 基本介绍

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

在这里插入图片描述

图1 哈希表

在这里插入图片描述

图2 哈希表的应用

3. 应用实例

题目:有一个公司,当有新元哦概念股来报道时,就将该员工的信息加入(id,name),当输入该员工的id时,要求找到该员工的所有信息

要求:不使用数据库,速度越快越好 => 哈希表

在这里插入图片描述

图3 程序结构框图

代码如下[包含 增 删 查]

class HashTab {  //哈希表
    //定义大小为size的EmpLinkedList数组
    private int size;
    private EmpLinkedList[] empLinkedLists;

    public HashTab(int size) {
        this.size = size;
        //设置大小
        empLinkedLists = new EmpLinkedList[size];
        //但是注意!!!
        //数组大小虽然决定了 但是数组里的元素默认初始化为null
        //即每个EmpLinkedList = null;
        //需要初始化
        for (int i = 0; i < size; i++) {
            empLinkedLists[i] = new EmpLinkedList();//初始化每个元素链表
        }
    }

    public void findEmpById(int no) {  //通过Id找对象
        //empLinkedLists[hashFun(no)] 找到对应的链表
        //.find(no) 在对应的链表中找相应的节点
        empLinkedLists[hashFun(no)].find(no);
    }

    public void delete(int no){ //根据编号删除对应元素
        //empLinkedLists[hashFun(emp.getId())] 找到对应的链表
        //.delete在对应的链表中删除节点
        empLinkedLists[hashFun(no)].delete(no);
    }

    public void add(Emp emp) {   //添加元素到哈希表中
        //empLinkedLists[hashFun(emp.getId())] 找到对应的链表
        //.add添加对象到对应的链表中
        empLinkedLists[hashFun(emp.getId())].add(emp);
    }

    public void list() { //显示哈希表中的数据
        for (int i = 0; i < size; i++) {
            empLinkedLists[i].list(i);   //依次显示每一条链表的数据
        }
    }

    public int hashFun(int no) {   //散列函数 用来决定数据放哪一个链表
        return no % size;   //返回编号对size的取模
    }
}

class EmpLinkedList {    //定义Emp链表
    private Emp head = null;    //定义头节点

    public void add(Emp emp) {   //添加新员工 直接添加到最后一个位置
        if (head == null) {   //如果头节点是空的
            head = emp; //直接把头节点指向次员工
            return;
        }
        Emp temp = head;
        while (temp.getNext() != null) {//遍历到最后一个节点退出循环
            temp = temp.getNext();   //继续下一个节点
        }
        //退出循环后 此节点指向最后一个节点
        temp.setNext(emp);  //将最后一个节点next指向新的节点
    }

    public void delete(int no) { //根据no号删除对应的节点
        if (head == null) {
            System.out.println("此处无垠三变量");
            return;
        } else if (head.getId() == no) {   //如果头节点就是要删除的对象
            head = head.getNext();  //则直接头节点后移就行了
            return;
        }

        Emp temp = head;
        while (temp.getNext() != null) {
            if (temp.getNext().getId() == no) { //如果下一个节点是删除的节点
                temp.setNext(temp.getNext().getNext()); //将temp的next指向后面第二位
                break;
            }
            temp = temp.getNext();  //否则后移 继续判断下一位
        }
    }

    public void find(int no) {   //查找对应no是否存在
        if (head == null) {
            System.out.println("目标不存在");
            return;
        }
        Emp temp = head;
        while (temp != null) {//遍历每一个节点
            if (temp.getId() == no) { //说明找到了对应的目标
                System.out.println(temp);   //输出对应的信息
                return;
            }
            temp = temp.getNext();   //继续下一个节点
        }
        //正常退出循环后 说明目标不存在
        System.out.println("目标不存在");
    }

    public void list(int no) { //显示链表
        if (head == null) {   //说明为空
            System.out.println("第" + (no + 1) + "条链表为空");
            return;
        }
        Emp temp = head;
        System.out.print("第" + (no + 1) + "条链表:");
        while (temp != null) {//遍历每一个节点
            System.out.print(temp + " ");
            temp = temp.getNext();   //继续下一个节点
        }
        System.out.println();
    }
}

class Emp {  //定义Emp节点

    private int Id; //编号
    private String name;    //名字
    private Emp next;   //指向下一个节点 默认为null

    public Emp(int id, String name) {   //构造器
        Id = id;
        this.name = name;
    }

    public Emp getNext() {
        return next;
    }

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

    public int getId() {
        return Id;
    }

    public void setId(int id) {
        Id = id;
    }

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "{" +
                "Id=" + Id +
                ", name='" + name + '\'' +
                ", next=" + (next == null ? null : next.hashCode()) +
                '}';
    }
}

其实整个代码不难理解,就是在链表的基础上,创建了多个链表进行管理。看韩老师敲一遍代码,自己就能敲出来了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/253095.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CodeBlocks定义异常:multiple definition of 和 first defined here

基于链表实现贪吃蛇案例时候&#xff0c;在CodeBlocks的CPP源文件定义函数和全局变量均报错 异常现象 在**自定义的cpp**文件定义全局变量、对象、函数等均出现重复定义和首次定义 multiple definition of Controller::showCopy() first defined here 异常解决方案 正确代码…

RabbitMQ手动应答与持久化

1.SleepUtil线程睡眠工具类 package com.hong.utils;/*** Description: 线程睡眠工具类* Author: hong* Date: 2023-12-16 23:10* Version: 1.0**/ public class SleepUtil {public static void sleep(int second) {try {Thread.sleep(1000*second);} catch (InterruptedExcep…

HashMap构造函数解析与应用场景

目录 1. HashMap简介 2. HashMap的构造函数 2.1 默认构造函数 2.2 指定初始容量和加载因子的构造函数 3. 构造函数参数的影响 3.1 初始容量的选择 3.2 加载因子的选择 4. 构造函数的应用场景 4.1 默认构造函数的应用场景 4.2 指定初始容量和加载因子的构造函数的应用…

海安行车记录仪avi杀病毒导致文件丢失的恢复案例

海安行车记录仪&#xff0c;听名字就知道是个小小小品牌&#xff0c;而且用的文件格式是比较古老的AVI&#xff0c;这种文件格式是微软设计的&#xff0c;后来并没有普及&#xff08;不支持4G以上大文件而且结构过于松散&#xff09;。这个恢复案例比较特殊的地方是不太清楚做过…

教师如何维护学生的自尊心

作为教师&#xff0c;我们不仅要传授知识&#xff0c;更要关心学生的身心健康&#xff0c;特别是他们的自尊心。自尊心是个人自我价值的重要体现&#xff0c;对学生的学习、生活和未来的发展都有深远的影响。因此&#xff0c;维护学生的自尊心是教师的重要责任。 教师要尊重每…

[Verilog] Verilog 操作符与表达式

主页&#xff1a; 元存储博客 文章目录 前言1. 操作符2. 操作数3 表达式总结 前言 1. 操作符 图片来源&#xff1a; https://www.runoob.com/ Verilog语言中使用的操作符包括&#xff1a; 算术操作符&#xff1a;加法()、减法(-)、乘法(*)、除法(/)、取模(%)、自增()、自减(–…

常用网安渗透工具及命令(扫目录、解密爆破、漏洞信息搜索)

目录 dirsearch&#xff1a; dirmap&#xff1a; 输入目标 文件读取 ciphey&#xff08;很强的一个自动解密工具&#xff09;&#xff1a; john(破解密码)&#xff1a; whatweb指纹识别&#xff1a; searchsploit&#xff1a; 例1&#xff1a; 例2&#xff1a; 例3&…

no module named ‘xxx‘

目录结构如下 我想在GCNmodel的model里引入layers的GraphConvolution&#xff1a;from GCNmodel.layers import GraphConvolution&#xff0c;但这样却报错no module named GCNmodel&#xff0c;而且用from layers import GraphConvolution也不行。然后用sys.path.appen(xxx)…

MySQL数据库,表的增量备份与恢复

1. 从物理与逻辑的角度 数据库备份可以分为物理备份和逻辑备份。物理备份是对数据库操作系统的物理文件&#xff08;如数据 文件&#xff0c;日志文件等&#xff09;的备份。这种类型的备份适用于在出现问题时需要快速恢复的大型重要数据库。 物理备份又可以分为冷备份&#xf…

Redis Cluster集群搭建 三主三从

Redis包下载 Linux&#xff1a; http://download.redis.io/releases/ Mac or Windows: https://redis.io/download/ 2.下载后解压进入文件夹&#xff08;本次我的Redis版本是6.2.14版本&#xff09; /redis/redis-6.2.14 开始安装 make instarll修改配置文件复制redis.conf 6…

Ubuntu 常用命令之 chmod 命令用法介绍

chmod是Linux系统下的一个命令&#xff0c;用于改变文件或目录的权限。它的名称是“change mode”的缩写。在Linux中&#xff0c;文件或目录的权限分为读&#xff08;r&#xff09;、写&#xff08;w&#xff09;和执行&#xff08;x&#xff09;三种&#xff0c;分别对应数字4…

Python redis安装使用教程

一、项目环境 Python 3.8.xredis-5.0.14 二、Redis 安装 下载地址&#xff1a;https://github.com/tporadowski/redis/releases 下载 Redis-x64-xxx.zip压缩包到你要安装的文件夹&#xff0c;解压即可 三、使用redis 打开一个 cmd 窗口&#xff0c;使用 cd 命令切换redis…

(5)shell命令以及Linux的权限

写在前面 本章我们将重点讲解 Linux 权限&#xff0c;这是 Linux 基础部分中非常重要的一部分。内容比较干&#xff0c;我会稍稍正经些去讲解。话不多说&#xff0c;我们直接切入正题。 shell 命令及运行原理 严格意义上说的是一个操作系统&#xff0c;我们称之为 —— &…

MDK编译过程和文件类型

MDK是一款IDE软件&#xff0c;具有&#xff0c;编辑&#xff0c;编译&#xff0c;链接&#xff0c;下载&#xff0c;调试等等的功能。 1.编译器介绍&#xff1a; MDK可以编译C/C文件和汇编文件&#xff0c;MDK只是一款IDE软件&#xff0c;那他内部使用的是什么编译器呢&#x…

【已解决】Java zip解压时候 malformed input off : 4, length : 1

需求&#xff1a;通过页面上传ZIP文件后&#xff0c;对zip文件进行解压。 遇到的错误&#xff1a;在进行zip解压的时候错误如下&#xff1a; 先看报错前的&#xff1a; /*** 解压缩ZIP文件* param zipFile ZIP文件* param destDir 目标路径*/ public static void zipDecompre…

HIVE窗口函数

什么是窗口函数 hive中开窗函数通过over关键字声明&#xff1b;窗口函数&#xff0c;准确地说&#xff0c;函数在窗口中的应用&#xff1b;比如sum函数不仅可在group by后聚合&#xff0c;在可在窗口中应用&#xff1b; hive中groupby算子和开窗over&#xff0c;shuffle的逻辑…

时序数据库选型TimescaleDB

最近要做一个数字车间的物联网项目&#xff0c;数据存储成了首先要解决的问题&#xff0c;整个车间一共104台数控机床&#xff0c;1s钟采集1次数据&#xff0c;360024365*1043,279,744,000 &#xff0c;一年要产生32亿条记录&#xff0c;这个数据量用常见的关系型数据库肯定是不…

phpMyAdmin的常见安装位置

nginx的日志显示有人一直在尝试访问phpMyAdmin的setup.php&#xff0c;用了各种位置。 其实我只有一个nginx&#xff0c;别的什么也没有。 47.99.136.156 - - [01:44:37 0800] "GET http://abc.com:80/phpMyAdmin/scripts/setup.php HTTP/1.0" 404 162 "-"…

新建vue3项目

三种方法 一. 第一种方式 1、操作步骤&#xff1a; 创建项目目录 vue create 项目名称选择配置方式 ? Please pick a preset: #选择一个配置 Default &#xff08;[Vue 3] babel, eslint&#xff09;Default &#xff08;[Vue 2] babel, eslint&#xff09;Manually select …

wordpress安装之正式开始安装wordpress

1、拉取wordpress镜像 docker pull wordpress 2、启动容器 启动容器&#xff0c;设置容器名为wordpress2并把80端口映射到宿主机的9988端口 docker run -it --name wordpress2 -p 9988:80 -d wordpress 3、查看容器状态 docker ps 4、安装wordpress博客程序 因为我们前面启…