哈希冲突的常见解决方法【附C++代码】

        在C++中,哈希表是一种常用的数据结构,用于实现快速的插入、删除和查找操作。

哈希表的核心在于哈希函数,它将输入的关键字转换为一个数组索引。然而,不同的关键字可能映射到相同的索引,这种情况称为哈希冲突。

有效地解决哈希冲突是确保哈希表性能的关键。

1. 开放地址法

概念:开放地址法是指当一个关键字映射的位置已经被占用时,会寻找下一个空闲的位置进行存放。查找时,若原位置没有找到,则按照同样的规则继续查找下一个可能的位置。

优点:实现简单,无需额外的数据结构。

缺点:可能会导致某些区域过于密集,影响性能;删除操作复杂

代码示例

#include <iostream>
#include <vector>class OpenAddressingHashTable {
public:explicit OpenAddressingHashTable(size_t size) : table(size, -1), used(size, false) {}void insert(int key) {size_t index = key % table.size();while (used[index]) {index = (index + 1) % table.size(); // 线性探测法}table[index] = key;used[index] = true;}bool search(int key) {size_t index = key % table.size();while (used[index]) {if (table[index] == key) return true;index = (index + 1) % table.size();}return false;}private:std::vector<int> table;std::vector<bool> used;
};

2. 链地址法(哈希桶)

概念:链地址法是在每个数组位置上挂接一个链表,所有映射到该位置的元素都存储在这个链表中。

优点:冲突少时效率高,支持动态扩容,删除操作简单。

缺点:链表过长时,查找效率降低。

代码示例(基于之前提供的哈希桶示例):

#include <iostream>
#include <list>
#include <vector>class HashBucket {
public:explicit HashBucket(size_t size = 10) : buckets(size) {}void insert(int key, std::string value) {size_t index = hashFunction(key);buckets[index].push_back({key, value});}std::string search(int key) {size_t index = hashFunction(key);for (const auto& pair : buckets[index]) {if (pair.first == key) {return pair.second;}}return "Not Found";}void remove(int key) {size_t index = hashFunction(key);auto& bucket = buckets[index];bucket.erase(std::remove_if(bucket.begin(), bucket.end(),[key](const auto& p){ return p.first == key; }),bucket.end());}private:std::size_t hashFunction(int key) const {return key % buckets.size(); // 简单的取模哈希函数}std::vector<std::list<std::pair<int, std::string>>> buckets;
};int main() {HashBucket hashTable;hashTable.insert(10, "Apple");hashTable.insert(25, "Banana");hashTable.insert(20, "Cherry");std::cout << "Search 10: " << hashTable.search(10) << std::endl; // 应输出 Applestd::cout << "Search 30: " << hashTable.search(30) << std::endl; // 应输出 Not FoundhashTable.remove(20);std::cout << "Search 20 after removal: " << hashTable.search(20) << std::endl; // 应输出 Not Foundreturn 0;
}

3. 再哈希法

概念:当发生冲突时,使用第二个哈希函数计算另一个位置,如果仍冲突,则继续使用第三个或更多哈希函数,直到找到空位。

优点:可以减少聚集现象。

缺点:需要设计多个哈希函数,增加了实现复杂度。

代码示例(简略示例):

class RehashHashTable {
public:void insert(int key) {size_t index = primaryHash(key);if (isOccupied(index)) {index = secondaryHash(key); // 假设这是第二个哈希函数// 可能需要更多的检查和重哈希直到找到空位}// 实际插入逻辑省略}private:size_t primaryHash(int key) { /* 主哈希函数实现 */ }size_t secondaryHash(int key) { /* 辅助哈希函数实现 */ }bool isOccupied(size_t index) { /* 检查位置是否已被占用 */ }
};

4. 建立公共溢出区(使用率低)

概念:当主表满时,额外分配一块区域作为溢出区,所有冲突的元素都放入这个区域,并以某种顺序(如链表)链接起来。

优点:实现简单。

缺点:查找效率较低,因为可能需要遍历整个溢出区。

        解决哈希冲突的策略各有优劣,选择哪种方法取决于具体的应用场景和性能要求。开放地址法适合内存有限且数据量不大的情况;链地址法则更适合数据量大且需要频繁插入删除的场景;再哈希法和建立公共溢出区则是针对特定需求的解决方案,可能在某些特殊场景下更为合适。

        在实际应用中,还需要考虑哈希函数的设计、哈希表的动态扩容机制等因素,以进一步优化性能。C++标准库中的std::unordered_mapstd::unordered_set就是使用了类似链地址法的实现,结合了动态扩容机制,提供了高效的哈希表操作接口。

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

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

相关文章

走进全球LED显示龙头艾比森,深挖逆势增长43%的数智化逻辑

在大环境不景气的情况下&#xff0c;有一家智能制造企业在2023年营收40亿&#xff0c;同比增长高达43%&#xff0c;海外营收增长约 46%&#xff0c;并且连续12年单品牌出口额第一。 这就是全球LED显示龙头艾比森。 5月9日&#xff0c;纷享销客带领近70位企业高管走进纷享销客…

使用Nginx将服务器目录、文件共享出来

1.配置映射路径&#xff0c;加入映射目录 location /abc/ { autoindex on; autoindex_localtime on; charset utf-8; alias /usr/mydir/; } 2.重载Nginx配置 nginx -s reload 3.访问 http://XXX.XXX.XXX.XXX/abc/ 即可 注&#xff1a; 如果…

短视频再度重逢:四川京之华锦信息技术公司

短视频再度重逢 在数字化时代的浪潮中&#xff0c;短视频以其独特的魅力迅速崛起&#xff0c;成为现代人生活中不可或缺的一部分。而当我们谈论起短视频&#xff0c;我们不仅仅是在谈论一种娱乐方式&#xff0c;更是在谈论一种情感的载体&#xff0c;一种回忆的媒介。今天&…

PHP8.0 match函数

match 表达式是 PHP 8.0 引入的一个新的控制结构&#xff0c;它提供了一种简洁且更强大的方式来进行条件匹配。与 switch 语句相比&#xff0c;match 表达式具有以下优势&#xff1a; 返回值&#xff1a;match 是一个表达式&#xff0c;它会返回一个值。严格比较&#xff1a;m…

MyBatis系统学习篇 - MyBatis逆向工程

MyBatis的逆向工程是指根据数据库表结构自动生成对应的Java实体类、Mapper接口和XML映射文件的过程。逆向工程可以帮助开发人员快速生成与数据库表对应的代码&#xff0c;减少手动编写重复代码的工作量。 我们在MyBatis中通过逆向工具来帮我简化繁琐的搭建框架&#xff0c;减少…

iOS推送证书过期处理

苹果推送证书的有效期都是一年&#xff0c;将要过期的时候&#xff0c;苹果官方会发邮件提醒。 一、过期 在电脑上找到并打开其它->钥匙串访问&#xff1b; 我的证书可以看到各个App的推送证书&#xff0c;如果过期了&#xff0c;显示红色X 二、重新创建 1、登陆apple开…

如何解决三层单点故障

我给他整成下面这样行不行呀 一个pc的默认网关只有一个&#xff0c;pc1配置的是1.1&#xff0c;那么路由坏了&#xff0c;他还是给1.1发送数据&#xff0c;冗余的那个也没用上呀 用VRRP&#xff08;虚拟路由冗余协议&#xff09;解决以上问题 那光把这个R1和R2虚拟成一个R3&…

android usb转串口

Android USB通信&#xff08;host转串口&#xff09;_android usb 实现串口通信-CSDN博客

Windows内核函数 - 文件的读操作

DDK提供了文件读操作的内核函数&#xff0c;其函数声明如下&#xff1a; NTSTATUS ZwWriteFile(IN HANDLE FileHandle,IN HANDLE Event,IN PIO_APC_ROUTINE ApcRoutine,IN PVOID ApcContext,out PIO_STATUS_BLOCK IoStatusBlock,IN PVOID Buffer,IN ULONG Length,IN PLARGE_IN…

windows 执行node报错 800A1391

在项目下执行node -v的时候&#xff0c;抛了这个错误&#xff0c;一开始没发现有啥问题 现在一看&#xff0c;这个报错里的node怎么是个文件... 出现这个问题&#xff0c;是因为项目下&#xff0c;有个同名的文件叫node.js&#xff0c;搞得windows一时不知道是想打开node.js文…

代码随想录算法训练营Day51 | 300.最长递增子序列 674. 最长连续递增序列 718. 最长重复子数组

代码随想录算法训练营Day51 | 300.最长递增子序列 674. 最长连续递增序列 718. 最长重复子数组 LeetCode 300.最长递增子序列 题目链接&#xff1a;LeetCode 300.最长递增子序列 思路&#xff1a; 选取最长子序列&#xff0c;并收集 class Solution { public:int lengthOfL…

通过提示工程将化学知识整合到大型语言模型中

在当今快速发展的人工智能领域&#xff0c;大型语言模型&#xff08;LLMs&#xff09;正成为科学研究的新兴工具。这些模型以其卓越的语言处理能力和零样本推理而闻名&#xff0c;为解决传统科学问题提供了全新的途径。然而&#xff0c;LLMs在特定科学领域的应用面临挑战&#…

第四十六天 | 279.完全平方数 139.单词拆分

题目&#xff1a;279.完全平方数 本题比较简单&#xff0c;几天没做背包但是这道题很快ac了 尝试解答&#xff1a; 题目类型&#xff1a;给定一个背包容量&#xff0c;求装满背包的最少物品数&#xff0c;且每个物品可以放多次&#xff0c;完全背包 1.dp[j]数组含义&#xff…

如何选择适合自己需求的扬州独立服务器方案?

在互联网时代&#xff0c;独立服务器是网络建设的重要组成部分。选择适合自己需求的扬州独立服务器方案至关重要。下面&#xff0c;我们将介绍如何选择合适的扬州独立服务器&#xff0c;并推荐莱卡云&#xff08;Lcayun&#xff09;服务器商。 明确需求 要明确自己的需求是什…

大型央企国企信创化与数字化转型规划实施方案(71页PPT)

方案介绍&#xff1a; 随着全球信息技术的迅猛发展&#xff0c;数字化转型已成为企业提升竞争力、实现可持续发展的必经之路。作为国家经济的重要支柱&#xff0c;大型央企国企在信创化与数字化转型方面承载着重要的责任和使命。本方案旨在通过系统性的规划和实施&#xff0c;…

rpc理解

rpc 远程过程调用 rpc与http的区别 1.性能高 2.使用复杂 3.可扩展性高 4 跨语言支持 5.可以使用服务发现&#xff0c;负载均衡&#xff0c;熔断降级 rpc远程调用&#xff0c;必须传输数据&#xff0c;需要序列化。 序列化有多种方式&#xff1a; jdk原生序列化&#xff0c…

Discourse 使用 DiscourseConnect 来进行用户数据同步

我们都知道 Discourse 的用户管理和设置都高度依赖电子邮件。 如果 Discourse 没有设置电子邮件 SMTP 的话&#xff0c;作为管理员是没有办法对用户邮箱进行修改并且通过验证的。 可以采取的办法是通过 Discourse 的 DiscourseConnect 来进行用户同步。 根据官方的说法&…

C++语法|虚函数与多态详细讲解(四)|哪些函数不能实现成虚函数和虚析构函数的理解

系列汇总讲解&#xff0c;请移步&#xff1a; C语法&#xff5c;虚函数与多态详细讲解系列&#xff08;包含多重继承内容&#xff09; 文章目录 哪些函数不能成为虚函数虚析构函数什么时候把基类的析构函数必须是线程虚函数 哪些函数不能成为虚函数 要回答这个问题&#xff0c…

如何取消公众号的在线客服绑定授权

1&#xff0c;功能设置 2&#xff0c;公众号设置 3&#xff0c;查看详情&#xff0c;取消

开发远程遥控情趣玩具软件,提供现成程序源码应具备哪些基础功能

以“东莞梦情智能”为参考&#xff0c;其提供的现成情趣玩具遥控软件程序源码&#xff0c;所具备哪些基础功能&#xff0c;看看它们如何让情趣玩具变得更加丰富多彩。 一、设备连接 设备连接是情趣玩具遥控软件的基础功能之一。“东莞梦情智能”的现成源码支持多种连接方式&am…