【数据结构2】哈希表、哈希表的应用(集合与字典、md5算法和文件的哈希值)

news2024/9/20 20:39:41

1 哈希表

哈希表一个通过哈希函数来计算数据存 储位置的数据结构,通常支持如下操作:
插入(键,值):插入键值对(键,值)
Get(key):如果存在键为键的键值对则返回其值,否则返回空值
删除():删除键为键的键值对

哈希表(Hash Table,又称为散列表),是一种线性表的存储结构。哈希表由一个直接寻址表和一个哈希函数组成。哈希函数h(k)将元素关键字k作为自变量,返回元素的存储下标。

解决哈希冲突使用:拉链法
拉链法:哈希表每个位置都连接一个链表,当冲突发生时,冲突的元素将被加到该位置链表的最后。

在这里插入图片描述

class LinkList:
    """
    单链表实现
    """

    # Node类表示链表中的一个节点
    class Node:
        def __init__(self, item=None):
            """
            初始化链表节点
            :param item: 节点存储的数据,默认为None
            """
            self.item = item  # 存储节点的数据
            self.next = None  # 指向下一个节点的指针,初始为None

    # LinkListIterator类用于实现链表的迭代器
    class LinkListIterator:
        def __init__(self, node):
            """
            初始化链表迭代器
            :param node: 链表的起始节点
            """
            self.node = node  # 保存当前节点,用于迭代

        def __next__(self):
            """
            获取链表中的下一个元素
            :return: 当前节点的数据
            :raises StopIteration: 如果没有更多节点,则停止迭代
            """
            if self.node:
                cur_node = self.node  # 保留当前节点
                self.node = cur_node.next  # 移动到下一个节点
                return cur_node.item  # 返回当前节点的数据
            else:
                raise StopIteration  # 如果没有更多节点,则停止迭代

        def __iter__(self):
            """
            返回迭代器对象自身
            :return: 迭代器对象自身
            """
            return self  # 返回迭代器对象自身,使其可以在for循环中使用

    def __init__(self, iterable=None):
        """
        初始化链表
        :param iterable: 可迭代对象,用于初始化链表的元素
        """
        self.head = None  # 链表头节点的引用,初始化为空
        self.tail = None  # 链表尾节点的引用,初始化为空
        if iterable:
            self.extend(iterable)  # 如果传入了可迭代对象,则扩展链表

    def append(self, obj):
        """
        在链表末尾添加一个新节点
        :param obj: 要添加的元素
        """
        s = LinkList.Node(obj)  # 创建一个新节点
        if not self.head:
            self.head = s  # 如果链表为空,将头节点和尾节点都指向新节点
            self.tail = s
        else:
            self.tail.next = s  # 将当前尾节点的next指针指向新节点
            self.tail = s  # 更新尾节点为新节点

    def extend(self, iterable):
        """
        扩展链表,将可迭代对象中的每个元素添加到链表中
        :param iterable: 可迭代对象
        """
        for obj in iterable:
            self.append(obj)  # 依次添加可迭代对象中的每个元素

    def find(self, obj):
        """
        查找链表中是否存在指定的元素
        :param obj: 要查找的元素
        :return: 如果找到目标元素,则返回True;否则返回False
        """
        for n in self:
            if n == obj:
                return True  # 如果找到了目标元素,返回True
        return False  # 如果遍历结束也没有找到目标元素,返回False

    def delete(self, obj):
        """
        从链表中删除指定的元素
        :param obj: 要删除的元素
        :return: 如果成功删除,返回True;否则返回False
        """
        current = self.head  # 当前节点,初始化为链表的头节点
        previous = None  # 前一个节点的引用,初始化为None
        while current:
            if current.item == obj:
                if previous:
                    previous.next = current.next  # 跳过当前节点
                else:
                    self.head = current.next  # 如果删除的是头节点,更新头节点
                if current == self.tail:
                    self.tail = previous  # 如果删除的是尾节点,更新尾节点
                return True  # 删除成功
            previous = current
            current = current.next
        return False  # 如果没有找到目标元素,返回False

    def __iter__(self):
        """
        返回链表的迭代器对象
        :return: 链表的迭代器对象
        """
        return self.LinkListIterator(self.head)  # 返回一个迭代器对象,从头节点开始迭代

    def __repr__(self):
        """
        返回链表的字符串表示形式
        :return: 链表的字符串表示形式,格式为"<<" + 元素 + ">>"
        """
        return "<<" + ",".join(map(str, self)) + ">>"  # 返回链表的字符串表示形式,元素之间用逗号分隔,整体用"<<"和">>"包围


# lk = LinkList([1, 2, 3, 4, 5])
# print(lk)
# for element in lk:
#     print(element)

class HashTable:
    """
    哈希表实现
    """

    def __init__(self, size=101):
        self.size = size  # 哈希表的大小
        self.T = [LinkList() for _ in range(self.size)]  # 初始化哈希表数组,每个位置是一个链表

    def h(self, k):
        """
        哈希函数,将键k映射到表中的索引位置
        """
        return k % self.size  # 计算哈希值

    def insert(self, k):
        """
        插入一个键到哈希表中
        """
        i = self.h(k)  # 计算键的哈希值,确定插入位置
        if self.find(k):
            print('重复插入')  # 如果键已存在,打印提示
        else:
            self.T[i].append(k)  # 将键插入到相应位置的链表中
            print(f'{k}插入成功')  # 插入成功提示

    def find(self, k):
        """
        查找哈希表中是否存在指定的键
        """
        i = self.h(k)  # 计算键的哈希值,确定查找位置
        return self.T[i].find(k)  # 在链表中查找键

    def delete(self, k):
        """
        从哈希表中删除指定的键
        """
        i = self.h(k)  # 计算键的哈希值,确定删除位置
        if self.T[i].delete(k):
            print(f'{k}删除成功')  # 删除成功提示
        else:
            print(f'{k}未找到')  # 如果键不存在,打印提示


# 使用示例
lk = HashTable()
lk.insert(1)
lk.insert(2)
lk.insert(3)
print(lk.find(2))  # 输出: True
print(lk.find(4))  # 输出: False
lk.delete(2)  # 删除键2
print(lk.find(2))  # 输出: False

2 哈希表的应用-集合与字典

字典与集合都是通过哈希表来实现的。
a={'name': 'Alex', 'age':18, 'gender': 'an'}
使用哈希表存储字典,通过哈希函数将字典的键映射为下标。
	假设h('name')=3,h('age')=1,h('gender')= 4,则哈希表存储为[None, 18,None,'Alex''Man']
如果发生哈希冲突,则通过拉链法或开发寻址法解决

3 哈希表的应用-md5算法和文件的哈希值

MD5(Message-Digest Algorithm 5)曾经是密码学中常用的哈希函数,可以把任意长度的数据映射为128 位的哈希值。
其曾经包含如下特征:
1.同样的消息,其MD5值必定相同;
2.可以快速计算出任意给定消息的MD5值:
3.除非暴力的枚举所有可能的消息,否则不可能从哈 希值反推出消息本身;
4.两条消息之间即使只有微小的差别,其对应的MD5 值也应该是完全不同、完全不相关的;
5.不能在有意义的时间内人工的构造两个不同的消息 使其具有相同的MD5值。

应用举例:文件的哈希值
算出文件的哈希值,若两个文件的哈希值相同,则可认为这两个文件是相同的。
因此:
1.用户可以利用它来验证下载的文件是否完整
2.云存储服务商可以利用它来判断用户要上传的文件 是否已经存在于服务么器上,
	从而实现秒传的功能,同时避免存储过多相同的文件副本。

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

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

相关文章

开发者学习类网站

目录 **1、CodeProject****2、simplilearn****3、VisuAlgo****4、Google AI****5、CodeWars****6、SourceForge****7、GeeksforGeeks****8、StackOverflow** 1、CodeProject 网址&#xff1a;https://www.codeproject.com/ CodeProject是一个免费公开自己写的代码与程序的优秀…

稀土阻燃协效剂在木质地板中的应用

木质地板作为一种天然材料&#xff0c;非常容易燃烧&#xff0c;因此需要采取措施来增强其阻燃性能。稀土阻燃协效剂基于稀土4f电子层结构带来的特有属性&#xff0c;在聚合物材料燃烧时可催化酯化成炭,迅速在高分子表面形成致密连续的碳层,隔绝聚合物材料内部的可燃性气体与氧…

vue项目png图片加载不出来的问题

前提&#xff1a;因为命名的时候 配合后端&#xff0c;所以把图片的名称设置成中文的例如&#xff1a;新增圆、新增方块等命名&#xff1b;提交到线上环境后&#xff0c;发现有些图片不能完全显示&#xff1b;鼠标移入查看地址&#xff0c;发现其他展示的图片已经转为base64的形…

SALib | 灵敏度分析Python工具箱

灵敏度分析Python工具箱 Sensitivity Analysis LibrarySupported MethodsInstallationRequirementsHow to cite SALibReference Sensitivity Analysis Library SALib是常用灵敏度分析方法的Python实现&#xff0c;包括 Sobol、Morris 和 FAST 方法。在系统建模中很有用&#x…

解决Element-plus中Carousel(走马灯)图片无法正常加载的bug

前言&#xff1a; 最近帮助朋友解决了一个使用Element-plus中Carousel&#xff08;走马灯&#xff09;图片无法正常加载的bug&#xff0c;经过笔者的不断努力终于实现了&#xff0c;现在跟大家分享一下&#xff1a; 朋友原来的代码是这样的&#xff1a; <template><…

代码随想录Day 23|回溯Part02,39.组合总和、40.组合总和Ⅱ、131.分割回文串

提示&#xff1a;DDU&#xff0c;供自己复习使用。欢迎大家前来讨论~ 文章目录 第七章 回溯算法part03一、题目题目一&#xff1a; 39. 组合总和解题思路&#xff1a;回溯三部曲剪枝优化小结&#xff1a; 题目二&#xff1a;40.组合总和Ⅱ解题思路&#xff1a;回溯三部曲 题目…

LabVIEW中CANopen Read SDO.vi 和 CANopen Read Write CAN Frame.vi区别

CANopen Read SDO.vi 和 CANopen Read Write CAN Frame.vi 都是 NI-Industrial Communications for CANopen 库中的示例 VI&#xff0c;用于与 CANopen 网络进行通信&#xff0c;但它们的功能和使用场景有所不同。以下是它们的主要区别&#xff1a; 1. 功能层次 CANopen Read W…

图像分割论文阅读:BCU-Net: Bridging ConvNeXt and U-Net for medical image segmentation

本文提出了一种集合ConvNeXt和U-Net优势的网络模型来分割医学图像。 当然&#xff0c;模型整体结构就是并列双分支&#xff0c;如果只是这些内容&#xff0c;不值得拿出来讲。 主要有意思的部分是其融合两分支的多标签召回模块&#xff08;multilabel recall loss module&…

Tutorial:Deep Learning for Remote Sensing Data

文章目录 0. Intro1. ADVANTAGES OF REMOTE SENSING METHODS2. THE GENERAL FRAMEWORK3. BASIC ALGORITHMS IN DEEP LEARNING3.1 CONVOLUTIONAL NEURAL NETWORKS3.1.1 CONVOLUTIONAL LAYER3.1.2 NONLINEARITY LAYER3.1.3 POOLING LAYER 3.2 AUTOENCODERS3.3 RESTRICTED BOLTZMA…

SEO古诗网,可做站群,可二开成泛——码山侠

数据量大&#xff0c;古诗&#xff0c;名句等一共有数十万数据&#xff0c;基本上所有的古诗词已经入库完。 模板SEO强大&#xff0c;做好了基本的优化配置&#xff0c;结合帝国强大的sinfo插件&#xff0c;百度推送插件&#xff0c;以及itag管理插件很容易形成词库。 帝国CM…

数据结构(邓俊辉)学习笔记】串 01——ADT

1. 定义 特点 我们讨论的主题是串&#xff0c;无论从抽象数据类型&#xff0c;还是从具体实现的角度来看&#xff0c;串&#xff0c;相当于此前所介绍的数据结构来说都更为简单。因此&#xff0c;会将更多的时间用于讨论串的相关算法&#xff0c;尤其是串匹配的算法。 在接下…

探寻孩子不会说话与自闭症的关联及成因

在孩子的成长过程中&#xff0c;语言的发展是一个至关重要的阶段。然而&#xff0c;有些孩子却迟迟不会说话&#xff0c;这让家长们忧心忡忡。而当孩子不会说话的同时还伴有一些异常行为时&#xff0c;自闭症的担忧便会涌上心头。那么&#xff0c;孩子不会说话且患有自闭症究竟…

最近再写一个仿微信的项目遇到的一些bug(一)

目录&#xff1a; bug &#xff08;一&#xff09;Property ‘sqlSessionFactory‘ or ‘sqlSessionTemplate‘ are requiredProperty报错解决方法 bug &#xff08;二&#xff09;Cannot invoke “javax.script.ScriptEngine.eval(String)“ because “engine“ is null报错原…

likeshop采集商品图片无法保存解决方案

封面图 一个修复单&#xff0c;客户的likeshop采集tb商品后&#xff0c;保存到商品库的时候 主图无法显示 报错&#xff1a; "/www/wwwroot/test.0ev.cn/server/public/uploads/l7pu2aqt/admin/images/d61d40dab9e6245f90b62ede72b51639.jpg" string(6226) "…

除毛大作战,选择你的清理工具——希喂、美的宠物空气净化器PK

随着气温的升高&#xff0c;又到了宠物的换毛季。猫咪在家里疯狂掉毛&#xff0c;而铲屎官也陷入清理难题。幸好&#xff0c;有宠物空气净化器可以帮助铲屎官减轻打扫负担。那么宠物空气净化器又该如何挑选呢&#xff1f;哪款宠物空气净化器效果更佳&#xff1f;我也很想知道答…

【JVM】剖析字符串与数组的底层实现(一)

剖析字符串与数组的底层实现 字符数组的存储方式 JVM有三种模型: 1.Oop模型:Java对象对应的C对象2.Klass模型:Java类在JVM对应的C对象3.handle模型 字符串常量池 即String Pool&#xff0c;但是JVM中对应的类是StringTable&#xff0c;底层实现是一个hashtable,如代码所示 …

老师怎样分班更便捷?

随着新学期的钟声敲响&#xff0c;老师们又迎来了一年中最繁忙的时刻。开学之初&#xff0c;除了要处理日常的教学事务&#xff0c;老师们还肩负着一项重要任务——给新生进行分班。 其实老师们完全可以不必那么劳累。在这个科技日新月异的时代&#xff0c;有许多工具可以帮助老…

计算机毕业设计选题推荐-高中素质评价档案系统-Java/Python项目实战

✨作者主页&#xff1a;IT毕设梦工厂✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…

SOMEIP_ETS_061: Sending_two_SOMEIP_Messages_in_a_row

测试目的&#xff1a; 验证设备&#xff08;DUT&#xff09;能够处理在单个UDP数据包中发送的多个SOME/IP消息&#xff0c;并对所有这些SOME/IP消息给出正确的响应。 描述 本测试用例旨在检查DUT在接收到一个包含多个SOME/IP消息的UDP数据包时&#xff0c;是否能够对所有包含…

如何使用MQTT订阅摄像机/NVR/DVR的AI报警

H5S内置MQTT服务&#xff0c;并把设备报警默认推送到MQTT服务器上&#xff0c;进入 设置-》协议-》MQTT配置MQTT服务参数&#xff0c;配置后需要重启生效。 MQTT开启后&#xff0c;就可以使用第三方MQTT客户端订阅事件&#xff0c;以下以MQTTX( https://mqttx.app/ )为例。 链…