哈希:闭散列的开放定址法

article/2025/8/12 7:25:05

我还是曾经的那个少年


1.概念

通过其要存储的值与存储的位置建立映射关系。

如:基数排序也是运用了哈希开放定址法的的思想。

弊端:仅适用于数据集中的情况

 2.开放定址法

 问题:按照上述哈希的方式,向集合插入数据为44,会出现什么问题呢?

哈希冲突。

即:不同关键字通过相同的哈希方式计算出相同的哈希地址,该种现象称为哈希冲突或哈希碰撞。

3.哈希冲突的解决方式

闭散列和开散列。(这次主要讲闭散列)

3.1闭散列

闭散列:也叫开放定址法,当发生哈希冲突时,如果哈希表未被装满,说明在哈希表中必然还有空位置,那么可以把key存放到冲突位置中的“下一个” 空位置中去那如何寻找下一个空位置呢?

 1.线性探测

比如上面的场景中,现在需要插入元素44,先通过哈希函数计算哈希地址,hashAddr4,因此44理论上应该插在该位置,但是该位置已经放了值为4的元素,即发生哈希冲突。

线性探测:从发生冲突的位置开始,依次向后探测,直到寻找到下一个空位置为止
  • 插入
    • 通过哈希函数获取待插入元素在哈希表中的位置
    • 如果该位置中没有元素则直接插入新元素,如果该位置中有元素发生哈希冲突, 使用线性探测找到下一个空位置,插入新元素

  • 删除

        采用闭散列处理哈希冲突时,不能随便物理删除哈希表中已有的元素,若直接删除元素会影

        响其他元素的搜索。比如删除元素4,如果直接删除掉,44查找起来可能会受影响。

        因此线性探测采用标记的伪删除法来删除一个元素

通过添加枚举常量,来标记相应位置上是否存在或为空等状态。

enum STASTE
{EXIST,EMPTY,DELETE
};
template<class K, class V>
struct HashData
{pair<K, V> _kv;STASTE _state = EMPTY;
};

线性探测:找到空(状态为:EMPTY),没找到才返回

3.1.1扩容问题  

4.插入的key值为字符串

我们需要将该字符串转换成相应的整数再进行映射。字符哈希算法。

 5.模拟实现

//整型(同时还解决了负数和浮点数的问题)
template<class K>
struct DefaultHashFunc
{size_t operator()(const K& key){return (size_t)key;}
};//模板特化
template<>
struct DefaultHashFunc<string>
{size_t operator()(const string& str){// BKDRsize_t hash = 0;for (auto ch : str){hash *= 131;hash += ch;}return hash;}
};
namespace open_address
{enum STASTE{EXIST,EMPTY,DELETE};template<class K, class V>struct HashData{pair<K, V> _kv;STASTE _state = EMPTY;};template<class K, class V, class HashFunc = DefaultHashFunc<K>>class HashTable{public:HashTable(){_table.resize(10);}bool insert(const pair<K, V>& kv){//是否存在if (find(kv.first))return false;//扩容if (_n * 10 / _table.capacity() >= 7){//类似现代写法HashTable<K, V, HashFunc> tmp;tmp.getTable().resize(_table.capacity() * 2);//遍历旧数据,重新映射到新空间for (size_t i = 0; i < _table.size(); i++){if (_table[i]._state == EXIST)tmp.insert(_table[i]._kv);}_table.swap(tmp.getTable());}//线性探索HashFunc hf;size_t hashi = hf(kv.first) % _table.size();while (_table[hashi]._state == EXIST){++hashi;hashi %= _table.size();}_table[hashi]._kv = kv;_table[hashi]._state = EXIST;++_n;return true;}HashData<const K, V>* find(const K& key){HashFunc hf;//先找到相应的映射位置,是则返回,否则继续往后查找到空为止size_t hashi = hf(key) % _table.size();while (_table[hashi]._state != EMPTY){if (hf(_table[hashi]._kv.first) == hf(key))return (HashData<const K, V>*) & _table[hashi];++hashi;hashi %= _table.size();}return nullptr;}bool erase(const K& key){HashData<const K, V>* ret = find(key);if (ret == nullptr || ret->_state == DELETE)return false;ret->_state = DELETE;--_n;return true;}vector<HashData<K, V>>& getTable(){return _table;}private:vector<HashData<K, V>> _table;size_t _n = 0;	//记录存储有效数据个数};
}

感觉不错的可以点赞+收藏咯!!

谢谢大家


http://www.hkcw.cn/article/vAOTXiTBlr.shtml

相关文章

数据库基础

MySQL基础 一、什么是数据库 mysql是数据库服务的客户端 mysql是数据库服务的服务器端 本质&#xff1a;基于C&#xff08;mysql&#xff09;S&#xff08;mysqld&#xff09;模式的一种服务网络&#xff0c;一套给我们提供数据存取的服务的网络程序 数据库&#xff1a;一…

多线程——线程池

课程&#xff1a; 什么是线程池 可以自己实现这个功能&#xff0c;自己写一个线程池 jdk也给提供了线程池 为什么要有线程池 Executor框架 任务&#xff1a;就是代码 执行&#xff1a;谁去执行这个代码&#xff0c;之前是Thread执行的&#xff0c; thread: Executor: …

2006-2021年 中国社会状况综合调查CSS数据(含Excel、Stata格式)

2006-2021年 中国社会状况综合调查CSS数据&#xff08;含Excel、Stata格式&#xff09;.ziphttps://download.csdn.net/download/2401_84585615/89784651 https://download.csdn.net/download/2401_84585615/89784651 2006至2021年&#xff0c;中国社会状况综合调查&#xff08…

ReLU的变体

在深度学习中&#xff0c;ReLU&#xff08;Rectified Linear Unit&#xff09;是最常用的激活函数之一&#xff0c;但其存在一些局限性&#xff08;如死亡ReLU问题&#xff09;。为解决这些问题&#xff0c;研究者们提出了多种变体。以下是常见的ReLU变体及其核心特点&#xff…

麦克风和电脑内播放声音实时识别转文字软件FunASR整合包V5下载

我基于FunASR制作的实时语音识别转文字软件当前更新到V5版本。软件可以实时识别麦克风声音和电脑内播放声音转为文字。 FunASR软件介绍 FunASR 是一款基础语音识别工具包和开源 SOTA 预训练模型&#xff0c;支持语音识别、语音活动检测、文本后处理等。 我使用FunASR制作了一…

Ollama 开放 局域网访问 外网访问 mac

目录 问题描述 搜索尝试 最终方案 问题描述 我们在本地安装Ollama模型后通过127.0.0.1:11434访问正常返回 但是无法通过局域网IP访问如&#xff1a; http://192.168.1.158:11434 搜索尝试 搜索发现需要添加环境变量 OLLAMA_HOST 才能开放外网访问 export OLLAMA_HOST0.0.…

让Windows“怀上”macOS,不要太漂亮

记得Windows 11刚发布时&#xff0c;很多人都说它“果味十足”&#xff0c;仿佛是在向macOS靠拢。虽然大家觉得Windows有点“没骨气”&#xff0c;但不得不承认&#xff0c;它的界面确实很美观。 今天给大家介绍两款软件&#xff0c;能让Windows拥有macOS的风格&#xff0c;看起…

Gradle配置指南:深入解析settings.gradle.kts(Kotlin DSL版)

文章目录 Gradle配置指南&#xff1a;深入解析settings.gradle.kts&#xff08;Kotlin DSL版&#xff09;settings.gradle.kts 基础配置选项单项目配置多项目配置 高级配置选项插件管理&#xff08;Plugin Management&#xff09;基础配置模板案例&#xff1a;Android项目标准配…

Android SDK安装与配置(小白教程)

目录 1、下载&#xff1a; 2、安装&#xff1a; 3、配置环境变量&#xff1a; 4、验证是否安装成功&#xff1a; Android SDK&#xff08;软件开发工具包&#xff09;是一套为开发者提供的全面工具和资源集合&#xff0c;涵盖不同版本平台、各类开发与调试工具、支持库等&a…

[wsl2]MacOS/Win局域网ssh连接wsl2:Ubuntu24.04 LTS

【wsl2】MacOS/Win局域网ssh连接wsl2&#xff1a;Ubuntu24.04 LTS 保证使用的是微软应用商店中下载的Ubuntu发行版本&#xff0c;本文在配置时发现若使用docker所基于的ubuntu系统配置会失败。遂采用默认的子发行版本。写在前面why wsl2&#xff1f;win11的好处 开始配置之前1.…

JAVA游戏打手俱乐部护航小程序+APP+公众号+h5 源码游戏陪玩小程序系统

一、系统概述 JAVA 游戏打手俱乐部护航陪玩系统是一款集小程序、APP、公众号和 H5 于一体的综合性游戏陪玩平台。该系统凭借丰富多样的功能&#xff0c;为游戏玩家和陪玩师傅搭建了便捷的沟通桥梁。其主要功能包括精准分类、优惠券管理、我的团队、师傅申请入驻、师傅端抢单机…

使用Mac下载MySQL修改密码第一篇_数据库

Mac下载MySQL MySQL官网链接MySQL​​​​​​ 当进入到官网后下滑到community社区&#xff0c;进行下载 然后选择community sever下载 这里就是要下载的界面&#xff0c;如果需要下载之前版本的话可以点击archives&#xff0c; 可能会因为这是外网原因&#xff0c;有时候下…

【Mac 从 0 到 1 保姆级配置教程 08】- 快速配置 Neovim、LazyVim 以及常用开发环境,如果之前有人这么写就好了

文章目录 2. 安装 Neovim3. 安装 LazyVim3.1. 安装依赖3.2. 安装 LazyVim3.3. 问题修复 4. 配置 LazyVim4.1. 基础知识4.2. 内置快捷键4.3. 自定义快捷键4.4. 配置主题4.5. 配置 C/C 环境4.6. 配置 JSON 和 Markdown 5. 最后6. 参考资料7. 系列教程 Mac 从 0 到 1 保姆级配置教…

Android SMS发送技术指南

本文还有配套的精品资源&#xff0c;点击获取 简介&#xff1a;本文详细介绍了在Android平台上如何使用编程接口&#xff08;API&#xff09;发送短信&#xff0c;包括 SmsManager 类的使用、调试技巧和设备兼容性处理。通过实例代码展示了如何实现文本消息的发送&#xf…

AndroidStudio创建Android虚拟机教程

前言 在 Android 开发的世界中&#xff0c;拥有一个可靠且灵活的测试环境是至关重要的。Android Studio 提供了虚拟设备&#xff08;AVD&#xff09;管理器&#xff0c;这是一个强大的工具&#xff0c;允许开发者创建自定义的虚拟设备来模拟不同的 Android 设备。通过 AVD&…

uniapp 小程序 web-view 打开H5页面传参以及调用postMessage回传参数

uniapp 小程序 web-view 打开H5页面传参以及调用postMessage回传参数 uniapp 运行微信小程序&#xff0c;在小程序内利用 web-view 打开H5页面进行数据流转的总结。 首先做点准备工作&#xff0c;官网明确的说了小程序是不支持本地的&#xff0c;那怎么进行调试呢&#xff0c;…

mac 下载nvm

先在终端查看是否安装brew brew -v显示版本&#xff0c;开始下一步&#xff0c;如果不显示版本&#xff0c;则需要先安装brew 安装brew 使用brew安装nvm 执行安装命令 brew install nvm配置环境变量 配置环境变量之前&#xff0c;先查看nvm下载的位置 brew list nvm这是…

Android的uid~package~pid的关系

UID &#xff1a; Linux 系统级用户标识&#xff0c;Android 中每个应用安装时分配唯一 UID&#xff08;如 1000&#xff09;。 Package&#xff1a; Android 应用包名(例如android)&#xff0c;一个 UID 可关联多个 Package&#xff08;共享 UID 场景如android:sharedUserI…

Rust 学习笔记:发布一个 crate 到 crates.io

Rust 学习笔记&#xff1a;发布一个 crate 到 crates.io Rust 学习笔记&#xff1a;发布一个 crate 到 crates.io提供有用的文档注释常用标题文档注释作为测试注释所包含的项目 使用 pub use 导出一个方便的公共 API设置 crates.io 账户添加 metadata 到一个新的 crate发布到 c…

大白话 Seata 分布式事务浅析,详解TCC模式

大家好&#xff0c;我是此林。 说到分布式事务&#xff0c;第一时间想到 Seata&#xff0c;它支持多种事务模型&#xff0c;比如&#xff1a;XA模式、AT模式、TCC模式、Saga模式(长事务)。 其中 TCC 模式是高性能分布式事务解决方案&#xff0c;适用于核心系统等对 性能有很高…