闭散列解决哈希冲突-----数据结构

解决哈希冲突——闭散列和开散列(数据结构) 提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录前言一、闭散列二、开散列1.引入库2.读入数据三、再散列(了解) 前言 提示:这里可以添加本文要记录的大概内容: 例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。 提示:以下是本篇文章正文内容,下面案例可供参考 一、闭散列 当发生哈希冲突时,从发生哈希冲突的位置开始按照某种方式找“下一个”空位置。 1.通过哈希函数计算哈希地址 2.插入元素----注意:可能 阅读详情

闭散列解决哈希冲突

闭散列(也称为开放地址法):一种解决哈希冲突的方法。

应用场景:

        对与闭散列的应用,我们可以举一个简单的实例:以函数为除留取余法的哈希函数进行构建哈希表,将会遇到剩余值相等的情况(如:有俩个关键字分别为2,1002,,最大范围为1000,则进行除模取余后,剩余值皆为2,此时就相当于出现了冲突),就是哈希冲突,本次我们将讨论解决冲突方法中的闭散列。闭散列就是,在满足可插入的前提下,将出现冲突的值进行向后寻找位置,找到空位置,将值放入,完成此次插入(同时解决了所遇到的哈希冲突)。

        可插入情况:就是计算插入总数量栈总数量的比率,也称为负载因子。

代码实现:

        对与闭散列,我们应了解其实质,即插入的时所遇到的几种情况,有数据、无数据和已删除数据。关于有数据和无数据这俩种情况其实很好理解,那么此处主要对已删除数据进行分析。提到已删除数据,我们就应思考一下哈希表的查询,对哈希表的查询过程中,如遇到所查值对应的地址为空,就进行返回的化,那么我们之前所作的工作(闭散列处理哈希冲突)将没有意义,因为在插入过程中,我们为了避免哈希冲突,对冲突数据进行了相应的处理(如”+1“查询)。故此时我们应该引入已删除数据这一种状态,使之不影响后序的查询、删除等一系列操作。

结构体代码:

typedef enum Stat { 
Empty, 
Valid, 
Deleted // 当前元素被删除了 
} Stat; 

typedef struct HashElem { 
KeyType key; 
ValType value; 
Stat stat; // 引入一个 stat 标记来作为是否有效的标记 
} HashElem; 

哈希初始化:

        1.判断非法输入

        2.对结构体内变量进行初始化

void HashInit(HashTable* ht, HashFunc hash_func){
    if(ht == NULL){
        //非法输入
        return;
    }  
    ht->size = 0;
    ht->func = hash_func;
    int i =0;
    for(;i<HashMaxSize;++i){
        ht->data[i].stat = Empty;        
    }
    return;
} 

哈希插入:

        1.判断非法输入,非法直接返回,反之继续;

        2.判断是否为"满",满直接返回,反之继续;

        3.应用哈希函数对关键字进行分析,得到哈希地址,进行地址状态检测

                a)状态为非“有数据状态",直接进行插入操作

                b)  状态为”有数据状态“,则对关键字进行+1处理,继续调用哈希函数,取哈希地址进行分析。

代码:

void HashInsert(HashTable* ht, KeyType key, ValType value){
    if(ht ==NULL||key<0){
        //非法输入
        return;
    }
    if(ht->size> 0.8*HashMaxSize){
        //哈希表已经达到上限
        return;
    }
    size_t offset = ht->func(key);
    while(1) {
        if(ht->data[offset].stat != Valid){
            ht->data[offset].key = key;
            ht->data[offset].value = value;
            ht->data[offset].stat = Valid;
            ++ht->size;
            return;
        }else if(ht->data[offset].stat == Valid&&ht->data[offset].key == key){
            //约定不能出现相同的key值
            return;
        }else{
            offset = (offset+1)%HashMaxSize;
        }
    }//while循环结束
} 

哈希查找:

        1.判断非法输入,非法直接返回,反之继续;

        2.判断是否为"空",为空直接返回,反之继续;

        3.调用哈希函数对关键字进行分析,得到哈希地址,进行地址状态检测

                a)状态为”无数据状态”直接返回,反之继续;

                b)状态为非“有数据状态“,关键字对比,查找到,返回相应的值,尾插找到进行+1操作继续。

                c)状态为”已删除数据状态”,直接进行+1操作继续。

代码:

// 输入key, 查找对应key的value. 
int HashFind(HashTable* ht, KeyType key, ValType* value){
    if(ht == NULL){
        //非法输入
        return 0;
    }
    if(ht->size == 0){
        //哈希表为空
        return 0;
    }
    size_t offset = ht->func(key);
    while(1){
        if(ht->data[offset].stat == Valid && ht->data[offset].key == key){
            *value = ht->data[offset].value;
            return 1;
        }else if(ht->data[offset].stat == Empty){
            return 0;
        }else{
            offset = (offset+1)%HashMaxSize;
        }
    }//while结束 
}

哈希删除:

        删除操作可以 分俩步进行,一、查找(方法同哈希查找),二、删除(需改相应哈希位置上的状态值)。

代码:

void HashRemove(HashTable* ht, KeyType key){
    if(ht == NULL){
        //非法输入
        return;
    } 
    KeyType offset = ht->func(key);
    while(1){
        if(ht->data[offset].stat == Valid && ht->data[offset].key == key){
            ht->data[offset].stat = Deleted;
            --ht->size;
            return;
        }else if(ht->data[offset].stat == Empty){
            return;
        }else{
            offset = (offset+1)%HashMaxSize;
        }
    }
}

哈希销毁:

        1.判断非法输入;

        2.修改结构体内容

代码:

void HashDestroy(HashTable* ht){
    if(ht == NULL){
        //非法输入
        return;
    }
    ht->size = 0;
    ht->func = NULL;
    return;
} 

哈希 :哈希冲突、负载因子、哈希函数、哈希表、哈希桶 文章目录哈希哈希(散列)函数 哈希 哈希(散列)是一种数据结构,通过散列算法将元素值转换为散列值进行存储。使得元素存储的位置与元素本身建立起了映射关系,如果要查、改数据,就可以直接到对应的位置去,使得时间复杂度达到了 O(1)。 哈希(散列)函数 哈希函数就是建立起元素与其存储位置的映射关系。 对于哈希函数来说,必须具有以下特点; 哈希函数的定义域必须包括需要存储的全部关键码,而如果散列表允许有m个地址时,其值域必须在0 到m-1之间 哈希函数计算出来的地址能均匀分布在整个空间中(防止产生密集的哈希冲突 阅读详情

相关推荐

openeuler在线/离线安装docker服务

openeuler在线/离线安装docker服务

haixuti7的博客 1071

解决哈希冲突(四种方法)

一、了解哈希表及哈希冲突 哈希表:是一种实现关联数组抽象数据类型的数据结构,这种结构可以将关键码映射到给定值。简单来说哈希表(key-value)之间存在一个映射关系,是键值对的关系,一个键对应一个值。 哈希冲突:当两个不同的数经过哈希函数计算后得到了同一个结果,即他们会被映射到哈希表的同一个位置时,即称为发生了哈希冲突。简单来说就是哈希函数算出来的地址被别的元素占用了。 二、解决哈希冲突办法 1、开放定址法:我们在遇到哈希冲突时,去寻找一个新的空闲的哈希地址。 举例:就是当我们去教室上课..

qq_48241564的博客 8万+

Paraview:Python Calculator Filter

python calculator过滤器 from paraview.simple import * connection = servermanager.Connect('localhost',11111) er = servermanager.sources.EnSightreader(CaseFileName='/.../data.case') er.PointArrays = ['x_velocity','1','y_velocity','1','z_velocity','1','cp','1']

haimianjie2012的专栏 3495

哈希冲突常用解决方法

1.基本概念 哈希算法:根据设定的哈希函数H(key)和处理冲突方法将一组关键字映象到一个有限的地址区间上的算法。也称为散列算法、杂凑算法。 哈希表:数据经过哈希算法之后得到的集合。这样关键字和数据在集合中的位置存在一定的关系,可以根据这种关系快速查询。 非哈希表:与哈希表相对应,集合中的数据和其存放位置没任何关联关系的集合。 由此可见,哈希算法是一种特殊的算法,能将任意数据散列后映射到有限的空间上,通常计算机软件中用作快速查找或加密使用。 哈希冲突:由于哈希算法被计算的数据是无限的,而计算后的结果范围有限

Doublelv 的博客专栏。 1万+

晶振(晶体振荡器)测试方法详解

晶振测试方法分为无源和有源两种类型。无源晶振(两脚)需用示波器测试波形,重点关注正弦波形状、200mV-1.5Vpp幅值和频率精度;有源晶振(四脚)通电后直接输出方波。测试要点包括:示波器使用10X探头、AC耦合,带宽需5倍于晶振频率;万用表可初筛短路/开路;替换法是工程最有效方法。常见故障排查顺序:供电→复位→焊接→型号→负载电容→波形观察→更换晶振→MCU配置。负载电容需按公式计算匹配,示波器观察是核心测试手段。

jiujiujinyuxi的博客 926

实战解析:利用Wireshark解密QQ通信协议

本文提供了一份利用Wireshark工具分析QQ通信协议的实战指南。文章详细介绍了从环境准备、捕获数据包到解析协议层的完整流程,重点演示了如何识别QQ号码字段、观察加密数据特征以及区分不同通信类型(如文本、文件传输)。通过此实践,读者可以深入理解网络分层模型和现代应用加密通信机制,提升网络协议分析与安全诊断能力。

weixin_29210727的博客 408

如何解决哈希冲突?

哈希表就是通过散列函数将键映射到定值,简单来说就是一个键对应一个值。而通过散列函数映射时将两个键映射到了同一个值,即这两个键将被哈希表映射到同一个位置,这种情况就被称为哈希冲突。

m0_62965917的博客 4556

Agent本地部署教程详细步骤

在开始之前,你需要明确你要部署的Agent是什么。如果你需要部署其他Agent,请参考其官方文档调整步骤。

weixin_39673931的博客 2502

解决Hash(哈希表)冲突的四种方案

哈希是一种通过对数据进行压缩, 从而提高效率的一种解决方法,但由于哈希函数有限,数据增大等缘故,哈希冲突成为数据有效压缩的一个难题。本文主要介绍哈希冲突、解决方案,以及各种哈希冲突的解决策略上的优缺点。哈希冲突即不同key值产生相同的地址,即发生了hash冲突。一般来说,哈希冲突是无法避免的,所以就有了解决方案。常见的解决Hash冲突的方案有开放寻址法、链地址法和再哈希法。

frozenpenguin的博客 1万+

STM32CubeIDE串口打印浮点数踩坑实录:5分钟搞定printf输出小数(附完整配置截图)

本文针对STM32CubeIDE中串口无法打印浮点数的常见问题,提供了详细的解决方案。核心在于通过添加“-u _printf_float”链接器参数,启用标准库的浮点数格式化支持。文章附有完整的配置截图和步骤,并提供了系统性的排查清单,帮助开发者快速解决printf输出小数的问题。

weixin_29163797的博客 343

ARFoundation系列讲解 - 24 锚点

一、添加平面检测和平面可视化 请参考 ARFounnation快速入门-08平面检测 案例 二、添加射线检测 1.在AR Session Origin 组件上添加ARRaycastManager 脚本

a451319296的博客 4877

解决hash冲突的四个方法

转自:https://www.cnblogs.com/wuchaodzxx/p/7396599.html 目录 开放定址法 线性探测再散列 二次探测再散列 伪随机探测再散列 再哈希法 链地址法 建立公共溢出区 优缺点 开放散列(open hashing)/ 拉链法(针对桶链结构) 封闭散列(closed hashing)/ 开放定址法 通过构造性能良好的哈希函数,可以减少冲...

liwenxia626的专栏 1615

ParaView: 从 2 或 3 个标量创建向量

ParaView: 从 2 或 3 个标量创建向量

希望我的博客,能帮上你解决学习中工作中所遇到的问题 585

【数据结构】—— 哈希表之闭散列解决哈希冲突

一、底层结构 unordered_set/map介绍 https://blog.youkuaiyun.com/chenxiyuehh/article/details/89737056 unordered_set/map应用 https://blog.youkuaiyun.com/chenxiyuehh/article/details/89964419 unordered系列的关联式容器之所以效率比较高,是因为其底层使用了...

chenxiyuehh的博客 1352

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

【数据结构】哈希结构--哈希冲突解决方法(闭散列)

**unordered系列的关联式容器在前面博客:[unordered系列] 中讲到了,这里我就讲一下: 1)底层的结构——哈希结构和哈希冲突 2)哈希冲突的解决方法——闭散列和[开散列]

ly_6699的博客 852

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

【数据结构】万字一文手把手解读哈希————(开/闭散列)解决哈希冲突完整详解(6)

本文详细解读了哈希,包括哈希冲突,哈希函数,详解了开放地址法闭散列,哈希桶开散列,以及基本使用;包含各过程代码设计解析,以及完整代码展示,cv可用

YYDsis的博客 2049

C++数据结构:哈希 -- unordered系列容器、哈希表的结构以及如何通过闭散列的方法解决哈希冲突

本文介绍了unordered系列的容器以及哈希的结构,并讲解了如何通过闭散列的方法解决哈希冲突然后进行了模拟实现

weixin_43908419的博客 2454

【C++进阶】哈希表(哈希函数、哈希冲突、开散列、闭散列)

首先对关键码集合用散列函数计算散列地址,具有相同地址的关键码归于同一子集合,每一个子集合称为一个桶,各个桶中的元素通过一个单链表链接起来,各链表的头结点存储在哈希表(又称哈希桶)中。比如中的场景,现在需要插入元素44,先通过哈希函数计算哈希地址,hashAddr为4,因此44理论上应该插在该位置,但是该位置已经放了值为4的元素,即发生哈希冲突。那如何寻找下一个空位置呢?当负载因子越大,哈希冲突的概率就越大,同时发生哈希踩踏的概率也越大,对于开放定址法,应该控制负载因子小于0.7,超过0.7则扩容。

2301_79551553的博客 1517

unordered系列关联式容器底层哈希结构的介绍,哈希表的模拟实现(哈希冲突的解决方法采用闭散列线性探测)

unordered系列关联式容器之所以处理数据的效率比较高,是因为底层使用了哈希结构,哈希结构的优点是:不经过任何比较,一次直接从表中得到要搜索的元素,通过某种函数(hashFunc)使元素的存储位置与它的关键码之间能够建立一一映射的关系,那么在查找时通过该函数可以很快找到该元素。

2401_84568462的博客 1397

哈希表之处理哈希冲突的闭散列方式

本文章主要介绍哈希的概念、关于处理哈希表中哈希冲突的闭散列方式以及代码实现其哈希表闭散列方式的插入查找删除操作!

谢广涛的博客 1816

高阶数据结构之哈希表基础讲解与模拟实现

哈希表(Hash Table)是一种高效的键值对存储数据结构,广泛应用于各种需要快速查找的场景,如数据库索引、缓存系统、集合等。它的基本思想是通过哈希函数将键映射到哈希表中的一个位置,从而实现快速的数据插入、删除和查找操作。下面我们将详细介绍哈希表的工作原理、实现方式、优缺点以及应用场景。哈希表作为一种重要的数据结构,提供了高效的查找、插入和删除操作。通过设计良好的哈希函数和适当的冲突解决策略,可以最大化哈希表的性能。

htw250056的博客 1394

详解数据结构之哈希表

哈希冲突,开散列,闭散列,代码模拟实现。

. 1万+

哈希表模拟实现

哈希表(Hash Table)是一种特殊的数据结构,主要用于快速实现数据的查找、插入和删除操作。哈希表的核心在于通过哈希函数(散列函数)将关键码值映射到表中一个位置来访问记录,从而加快查找速度。哈希表由一个存放记录的数组组成,这个数组被称为散列表。

weixin_66404215的博客 1133

哈希表以及哈希冲突

我们在前面讲解了TerrMap(Set)的底层是一个搜索二叉树,同时Set和Map还存在HashSet(Map)类,但是HahsMap(Set)到底是什么呢?本章来详细介绍以下。

weixin_67807492的博客 2841

C++语法(22)---- 哈希表的闭散列和开散列

关于哈希表的相关知识

竹杖芒鞋轻声马 1200

数据结构—hash表

哈希表,是根据键值对(Key  --- value)进行访问的数据结构。也就是说,它通过把key值映射到表中一个位置来访问记录,以加快查找的速度。给定表ht,存在函数f(key),对任意给定的关键字值key,代入函数后若能得到包含该关键字的记录在表中的地址,则称表M为哈希(Hash)表,函数f(key)为哈希(Hash) 函数。总结上面的所说:        若在Hash表中存放数据的是一个结构体...

luhaowei0066的博客 821
上一篇: 浅谈IO多路转接之select-----基础网络
下一篇: 开散列解决哈希冲突-----数据结构
CYD、孤狼
博客等级 码龄9年 24粉丝 129原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值