从0开始的算法(数据结构和算法)基础(五)

news2024/9/20 9:44:40

哈希表

哈希表是什么?

      哈希表(Hash Table)是一种数据结构,用于快速存储和查找数据。它通过将键(key)映射到数组中的索引位置来实现高效的查找、插入和删除操作。 乍一看不明白很正常,如果你学过数据库就会觉得很熟悉,哈希表的功能拓展一下不就是数据库中的表。
以下是哈希表与数据库之间概念对应的对比表格:

概念哈希表数据库
数据存储结构键(Key)与值(Value)主键(Primary Key)、字段(Column)
数据操作插入(Insert)、查找(Lookup)、删除(Delete)插入(INSERT)、查询(SELECT)、删除(DELETE)
数据关系独立性支持关系(Relation),通过外键建立关联
数据一致性与事务无事务支持支持ACID特性,具备事务管理
查询能力简单查找支持复杂查询,使用SQL
数据持久性内存存储持久化存储,通常存储在磁盘上

      一维的哈希,组成二维的表,二维表组成关系数据库。而且数据库里面也有基于这个数据结构的哈希索引。
      再看一下sql语句,是不是两个重合了。

String sql = "INSERT INTO teacher(id, username, password) VALUES (?, ?, ?)";

使用数组和链表实现哈希表

1. 数组实现

我们可以使用一个简单的数组来存储键值对。每个元素将是一个链表,用于处理冲突。在哈希表中,我们将数组中的每个空位称为桶(桶就像一个容器,可以存放多个元素。在哈希表中,多个键可能会映射到同一个哈希值,导致冲突。每个桶就是一个用来存储这些冲突元素的地方。)

数组实现的哈希表类
class Node {
    String key;
    int value;
    Node next;

    public Node(String key, int value) {
        this.key = key;
        this.value = value;
        this.next = null;
    }
}

class HashTable {
    private Node[] table;
    private int size;

    public HashTable(int size) {
        this.size = size;
        this.table = new Node[size]; // 创建一个数组
    }

    private int hashFunction(String key) {
        return key.hashCode() % size; // 使用哈希函数
    }

    public void insert(String key, int value) {
        int index = hashFunction(key);
        Node newNode = new Node(key, value);

        // 插入到链表头
        newNode.next = table[index];
        table[index] = newNode;
    }

    public Integer search(String key) {
        int index = hashFunction(key);
        Node current = table[index];

        while (current != null) {
            if (current.key.equals(key)) {
                return current.value;
            }
            current = current.next;
        }
        return null; // 未找到
    }

    public boolean delete(String key) {
        int index = hashFunction(key);
        Node current = table[index];
        Node prev = null;

        while (current != null) {
            if (current.key.equals(key)) {
                if (prev != null) {
                    prev.next = current.next; // 删除节点
                } else {
                    table[index] = current.next; // 删除头节点
                }
                return true;
            }
            prev = current;
            current = current.next;
        }
        return false; // 未找到
    }
}

2. 使用链表实现

假设我们不使用数组,而是使用链表实现哈希表的所有功能。这种方法可能不是最优的,但可以帮助理解哈希表的基本操作。

链表实现的哈希表类
class LinkedList {
    private Node head;

    public void insert(String key, int value) {
        Node newNode = new Node(key, value);
        newNode.next = head;
        head = newNode;
    }

    public Integer search(String key) {
        Node current = head;
        while (current != null) {
            if (current.key.equals(key)) {
                return current.value;
            }
            current = current.next;
        }
        return null; // 未找到
    }

    public boolean delete(String key) {
        Node current = head;
        Node prev = null;

        while (current != null) {
            if (current.key.equals(key)) {
                if (prev != null) {
                    prev.next = current.next; // 删除节点
                } else {
                    head = current.next; // 删除头节点
                }
                return true;
            }
            prev = current;
            current = current.next;
        }
        return false; // 未找到
    }
}

3. 使用示例

可以使用以上代码创建一个哈希表并进行基本操作:

public class Main {
    public static void main(String[] args) {
        HashTable ht = new HashTable(10);
        ht.insert("apple", 1);
        ht.insert("banana", 2);
        
        System.out.println("Searching for 'apple': " + ht.search("apple"));  // 输出: 1
        ht.delete("apple");
        System.out.println("Searching for 'apple' after deletion: " + ht.search("apple"));  // 输出: null
        
        // 使用链表实现
        LinkedList list = new LinkedList();
        list.insert("orange", 3);
        System.out.println("Searching for 'orange': " + list.search("orange")); // 输出: 3
    }
}

为什么我们需要使用哈希表(哈希表的实际应用)

哈希表在实际中的应用非常广泛,涵盖了各个领域。下面列出几个具体的实例及其对应的功能:

2. 数据去重

  • 功能:在处理大量数据时,通过哈希表快速判断数据是否已存在,避免重复。
  • 实例
    • Twitter:使用哈希表来快速去重用户提交的内容,如推文和图片,确保内容唯一性。

2. 编译器

  • 功能:存储和查找编程语言中的标识符及其相关信息。
  • 实例
    • GCC (GNU Compiler Collection):在编译过程中使用哈希表来维护符号表,存储变量、函数等标识符信息。
      在这里插入图片描述

3. 数据库索引

  • 功能:加速数据库查询操作,通过哈希表快速找到记录的位置。
  • 实例
    • MySQL:使用哈希索引来加速某些类型的查询,特别是针对唯一键的查找。在这里插入图片描述

4. 词频统计

  • 功能:在文本处理中,通过哈希表快速统计词频,进行文本分析。现在比较火的深度学习自然语言处理
  • 实例
    • NLTK (Natural Language Toolkit):一个用于自然语言处理的库,使用哈希表来统计词频、构建词典等。

5. 在线购物车

  • 功能:管理用户购物车中的项目,快速添加、删除和查找产品。
  • 实例
    • Amazon:使用哈希表来管理购物车中的物品,确保快速响应用户的添加和删除操作。

6. 域名解析系统(DNS)

  • 功能:将域名映射到对应的 IP 地址,使用哈希表实现快速查找。
  • 实例
    • Google DNS:提供快速和可靠的域名解析服务,背后使用哈希表来加速域名到 IP 地址的映射过程。

哈希冲突

哈希冲突(Hash Collision)是指在使用哈希表时,不同的输入数据通过哈希函数得到相同的哈希值(也称为哈希码)的现象。由于哈希表的基本原理是在一定范围内将数据映射到哈希值,因此哈希冲突是不可避免的,即使在理想情况下也会发生。

原因

哈希冲突发生的主要原因是因为哈希函数将一个非常大的数据集映射到一个固定长度的哈希值空间。因为这个空间是有限的,所以当数据量足够大时,不同的数据可能会被映射到同一个哈希值。

处理哈希冲突的方法

为了解决哈希冲突,通常有以下几种常见的方法:

  1. 开放寻址法(Open Addressing)

    • 线性探测(Linear Probing):当发生冲突时,按照固定的步长(通常是1)向前查找下一个空闲位置。
    • 二次探测(Quadratic Probing):与线性探测类似,但步长是二次方序列(1, 4, 9, …),以减少聚集现象。
    • 双重哈希(Double Hashing):使用第二个哈希函数生成探测序列,以解决一次哈希函数的局限性。
  2. 链地址法(Chaining)

    • 链表法:每个哈希表的槽位存储一个链表,当发生冲突时,将数据插入到对应槽位的链表中。
    • 树状结构:将链表替换为其他数据结构,如平衡树,以加速查找操作。

示例

假设我们有一个简单的哈希函数 h(x) = x % 10,将整数映射到哈希表中。对于输入数据 1525,计算得到的哈希值都是 5。如果采用链地址法处理冲突,哈希表中槽位 5 将存储一个链表,其中包含元素 1525

持续更新中~~ 欢迎评论留言

  • 从0开始的算法(数据结构和算法)基础(一)
  • 从0开始的算法(数据结构和算法)基础(二)
  • 从0开始的算法(数据结构和算法)基础(三)
  • 从0开始的算法(数据结构和算法)基础(四)

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

国外一个免费的PDF转图片的网站,WPS VIP才能享受的大量功能,这里都有了。

国外一个免费的PDF转图片的网站,WPS VIP才能享受的大量功能,这里都有了。https://imagestool.com/ 免费PDF转图片 等WPS收费功能 【慧哥开源充电桩平台】下载源码地址 https://liwenhui.blog.csdn.net/article/details/134773779?spm1001.2014.3001.55…

入侵检测技术

课程目标 了解需要入侵检测技术的原因 熟知入侵检测系统(IDS)的概念、结构、分类及作用 掌握入侵检测技术及其应用 目录 Why 为什么要学习IDS 1.防火墙不能保证绝对的安全 网络边界的设备 自身可以被攻破 对某些攻击保护很弱 不是所有的威胁来自…

分而治之?如何高效提炼大型语言模型的推理能力

人工智能咨询培训老师叶梓 转载标明出处 虽然大模型(如GPT-4)在开放域问答(ODQA)、数学、科学以及自主智能体等领域展现出了非凡的推理能力,但是这些模型在进行复杂推理时,往往需要处理大量的参数&#xff…

项目管理中,项目经理有哪些优势?

项目经理在项目管理中扮演着至关重要的角色,他们的优势主要体现在以下几个方面: 一、计划与组织能力 超强的计划能力:项目经理需要制定各种计划,因此更擅长制定精确、合理的项目计划。他们能够有效地分解项目任务,排…

Elastic 基于 RAG 的 AI 助手:使用 LLM 和私有 GitHub 问题分析应用程序问题

作者:来自 Bahubali Shetti 作为 SRE,分析应用程序比以往任何时候都更加复杂。你不仅必须确保应用程序以最佳方式运行以确保出色的客户体验,而且在某些情况下还必须了解内部工作原理以帮助排除故障。分析基于生产的服务中的问题是一项团队运动…

麒麟V10系统 arm架构 安装docker

查看服务器环境 ## 查看系统版本,确认版本 cat /etc/kylin-release## 操作系统 uname -p## 内核版本(≥ 3.10) uname -r## iptables 版本(≥ 1.4) iptables --version iptables v1.8.1 (legacy)# 我这边是arm64/v8 架…

首届中文NL2SQL挑战赛亚军比赛攻略_BugCreater

关联比赛: 首届中文NL2SQL挑战赛 1. 任务描述 本次比赛的任务:根据Question、表格信息(包含列名、列类型、内容),预测对应的SQL语句(下图黄色部分)。比赛只涉及单表查询,需要预测的有4部分&a…

pointofix下载与调整中文

想要在屏幕上批注,用pointofix最好,本篇文章告诉你如何下载pointofix和把pointofix语言弄成中文。 首先打开pointofix官网下载pointofix的安装包。 Pointofix - Herunterladen - Downloadhttps://www.pointofix.de/download.php点击这个pointofix180de…

基于CentOS Stream 9平台搭建Nacos2.4.0.1集群,并使用OpenResty反向代理集群,GRPC协议配置

目录展示 Nacos2.4.0.1集群搭建1. 下载2. 解压3.修改配置3.1分别修改下启动类中JDK路径以及启动大小3.2 分别配置数据源 修改端口去掉前面的#注释(修改数据库地址、数据库用户名、密码)If use MySQL as datasource:Count of DB:Connect URL of DB:密钥鉴…

SQL注入实例(sqli-labs/less-9)

0、初始页面 1、爆库名 使用python脚本 def inject_database1(url):name for i in range(1, 20):low 32high 128mid (low high) // 2while low < high:payload "1 and if(ascii(substr(database(),%d,1)) > %d ,sleep(2),0)-- " % (i, mid)res {"…

项目管理证书 PMP 的含金量高吗?详解分析

有用就是好的&#xff0c;我觉得PMP在项目管理领域非常实用。特别是对我这样刚入门的新手来说&#xff0c;PMP证书和项目管理思维方式对我有很大帮助。因为我刚开始接触这个领域&#xff0c;所以能够接受正确的思维指引&#xff0c;比起那些有经验但可能存在错误思维的经理来说…

word操作技巧

查看word的标题和大纲 参考自&#xff1a; ​​​

C++ 80行 极简扫雷

一共5346个字符&#xff0c;MinGW编译通过&#xff08;强烈不建议写这种代码&#xff01;&#xff01;&#xff01;&#xff09; 压行规则&#xff1a;一行不超过80个字符 代码&#xff1a; #include<windows.h> #include<stdio.h> #include<time.h> #def…

JVM知识总结(垃圾收集算法)

文章收录在网站&#xff1a;http://hardyfish.top/ 文章收录在网站&#xff1a;http://hardyfish.top/ 文章收录在网站&#xff1a;http://hardyfish.top/ 文章收录在网站&#xff1a;http://hardyfish.top/ 垃圾收集算法 分代收集理论 分代思想就是将堆分为新生代和老年代…

Tkinter 转载 (来自C语言中文网)

一个最简单的Tkinter程序至少应包含以下4个部分&#xff1a; 导入tkinter模块、创建主窗口、也称root窗口&#xff08;即根窗口&#xff09;、添加人机交互控件&#xff0c;同时编写相应的事件函数、通过主循环&#xff08;mainloop&#xff09;来显示主窗口。 以上&#xff…

[Git] fatal: the remote end hung up unexpectedly

1 问题介绍 在使用Git进行代码管理和版本控制的过程中&#xff0c;许多开发者可能会遇到这样一个错误提示&#xff1a;fatal: the remote end hung up unexpectedly。这是一种常见的错误&#xff0c;通常出现在将本地代码推送&#xff08;push&#xff09;到远程仓库&#xff…

新加坡物理服务器详细测评数据

新加坡物理服务器因其地理位置优越、网络连接质量高以及数据中心设施完善等因素&#xff0c;成为了许多企业和个人选择托管其业务的理想之地。以下是对新加坡物理服务器的一些详细测评数据的科普文&#xff0c;旨在帮助读者更好地了解这类服务器的性能和特点。 新加坡物理服务器…

智能制造与工业物联网CC2530——串口通讯、定时器唤醒

一、项目目的&#xff1a; 1.1 任务1&#xff1a;ZigBee 模块串口通信 任务背景&#xff1a; 熟悉 ZigBee 模块的硬件接口是使用该技术的基础。通过学习如何利用 IAR 开发环境设计程序&#xff0c;可以实现 CC2530 与 PC 机终端之间的串口通信&#xff0c;从而更好地理解和应用…

中断、异常

文章目录 概念CPU怎么直到中断/异常跳过来执行哪一个函数呢&#xff1f;LR 中断硬件框架&#xff1a;对于F103这块芯片&#xff0c;如果要PA0发出中断&#xff0c;那要做的操作有&#xff1f;GPIO中断编程具体代码 概念 中断属于一种异常 保存现场、处理异常&#xff08;中断…

C# 植物大战僵尸---杂交版

开发框架&#xff1a;.Net Fra,ework4.0 游戏名称&#xff1a;植物大战僵尸-杂交版 游戏介绍&#xff1a;植物大战僵尸-杂交版是一款结合了经典塔防游戏《植物大战僵尸》的元素和创新杂交机制的游戏。玩家需要种植各种植或英雄物来抵御一波又一波的僵尸入侵。游戏的特色在于各…