【数据结构 09】哈希

哈希算法:哈希也叫散列、映射,将任意长度的输入通过散列运算转化为固定长度的输出,该输出就是哈希值(散列值)。

哈希映射是一种压缩映射,通常情况下,散列值的空间远小于输入值的空间。

哈希运算的结果称为哈希值,哈希运算是不可逆过程,即不能通过哈希值推算出原值。

哈希运算常用于加密、位图、布隆过滤,位图的作用是海量数据的标记,布隆过滤器的作用是提高海量数据查询的效率(客户端向服务端查询数据)。

一、哈希函数

HashFunc.h

#pragma once
#include <iostream>// 仿函数
template<class K>
struct HashFunc
{size_t operator()(const K& key){return (size_t)key;}
};// 特化
template<>
struct HashFunc<std::string>
{size_t operator()(const std::string& str){size_t res = 0;for (const auto& ch : str){res *= 131;	// 随机数取值,避免哈希冲突res += ch;}return res;}
};

哈希表:将数据根据哈希运算得到哈希值(关键值),再根据哈希值将数据映射在表中,哈希表通常情况是一个vector容器。哈希表分为闭散列和开散列(哈希桶)。

哈希表的数据增删与红黑树差别不大,各有优劣,但是哈希表的数据查询效率远高于红黑树。

二、闭散列

#define _CRT_SECURE_NO_WARNINGS 1#pragma
#include <iostream>
#include <vector>
#include "HashFunc.h"enum status
{EMPTY,EXIST,DELETE
};template<class K, class V>
struct CloseHashNode
{std::pair<K, V> _kv;status _status = EMPTY;
};template<class K, class V, class Hash = HashFunc<K>>
class CloseHash
{typedef CloseHashNode<K, V> Data;
public:CloseHash(): _n(0){_table.resize(10);}bool Insert(const std::pair<K, V>& kv){if (Find(kv.first))return false;// 负载因子为0.7if (_n * 10 / _table.size() >= 7){std::vector<Data> newTable;newTable.resize(2 * _table.size());for (int i = 0; i < _table.size(); ++i){if (_table[i]._status == EXIST){size_t pos = Hash()(_table[i]._kv.first) % newTable.size();while (newTable[pos]._status != EMPTY){pos = (++pos) % newTable.size();}newTable[pos] = _table[i];}}_table.swap(newTable);}size_t pos = Hash()(kv.first) % _table.size();while (_table[pos]._status != EMPTY){pos = (++pos) % _table.size();}_table[pos]._kv = kv;_table[pos]._status = EXIST;++_n;return true;}Data* Find(const K& key){size_t pos = Hash()(key) % _table.size();int cnt = 0;while (_table[pos]._status != EMPTY && cnt != _table.size()){if (key == _table[pos]._kv.first && _table[pos]._status == EXIST)return &_table[pos];pos = (++pos) % _table.size();++cnt;}return nullptr;}bool Erase(const K& key){Data* ret = Find(key);if (ret){ret->_status = DELETE;--_n;return true;}else{return false;}}private:std::vector<Data> _table;size_t _n;
};

三、开散列

开散列也称哈希桶,哈希桶的vector节点存储的是数据节点,相同哈希值的节点以链表的形式存储在同一个vector位置上,当节点数与vector容量的比值为平衡因子值(1)时,哈希桶扩容,扩容时重新遍历原表,将原表的元素重新取哈希进行映射,为了提高效率,不拷贝节点,而是改变节点的指向。

#define _CRT_SECURE_NO_WARNINGS 1#pragma once
#include <iostream>
#include <vector>
#include "HashFunc.h"template<class K, class V>
struct OpenHashNode
{std::pair<K, V> kv;OpenHashNode<K, V>* next;OpenHashNode(const std::pair<K, V>& x): kv(x), next(nullptr){}
};template<class K, class V, class Hash = HashFunc<K>>
class OpenHash
{typedef OpenHashNode<K, V> Node;
public:OpenHash(): _n(0){_table.resize(10, nullptr);}bool Insert(const std::pair<K, V>& kv){if (Find(kv.first))return false;// 检查扩容,平衡因子为 1if (_n == _table.size()){std::vector<Node*> newTable;newTable.resize(2 * _table.size(), nullptr);for (int i = 0; i < _table.size(); ++i){Node* cur = _table[i];while (cur){Node* next = cur->next;size_t pos = Hash()(cur->kv.first) % newTable.size();cur->next = newTable[pos];newTable[pos] = cur;cur = next;}}_table.swap(newTable);}// 插入新节点Node* newNode = new Node(kv);size_t pos = Hash()(newNode->kv.first) % _table.size();newNode->next = _table[pos];_table[pos] = newNode;++_n;return true;}Node* Find(const K& key){size_t pos = Hash()(key) % _table.size();Node* cur = _table[pos];while (cur){if (cur->kv.first == key)return cur;cur = cur->next;}return nullptr;}bool Erase(const K& key){Node* ret = Find(key);if (ret){size_t pos = Hash()(key) % _table.size();Node* cur = _table[pos];if (cur == ret){cur = ret->next;delete ret;ret = nullptr;}else{while (cur->next != ret){cur = cur->next;}cur->next = ret->next;delete ret;ret = nullptr;}--_n;return true;}else{return false;}}private:std::vector<Node*> _table;int _n;
};

四、测试

#define _CRT_SECURE_NO_WARNINGS 1#include "CloseHash.h"
#include "OpenHash.h"
using namespace std;void TestCloseHash()
{cout << "CloseHash: " << endl << endl;CloseHash<int, int> hash;int arr[] = { 34, 36, 12, 54, 5, 22, 65, 32, 13, 4, 1, 52 };for (auto& e : arr){hash.Insert(make_pair(e, e));}cout << hash.Find(12) << endl;cout << hash.Find(22) << endl;cout << hash.Find(32) << endl;cout << hash.Find(42) << endl;cout << hash.Find(52) << endl;cout << endl;hash.Erase(32);cout << hash.Find(12) << endl;cout << hash.Find(22) << endl;cout << hash.Find(32) << endl;cout << hash.Find(42) << endl;cout << hash.Find(52) << endl;
}void TestOpenHash()
{cout << endl << endl << "OpenHash: " << endl << endl;OpenHash<int, int> hash;int arr[] = { 34, 36, 12, 54, 5, 22, 65, 32, 13, 4, 1, 52 };for (auto& e : arr){hash.Insert(make_pair(e, e));}cout << hash.Find(12) << endl;cout << hash.Find(22) << endl;cout << hash.Find(32) << endl;cout << hash.Find(42) << endl;cout << hash.Find(52) << endl;cout << endl;hash.Erase(32);cout << hash.Find(12) << endl;cout << hash.Find(22) << endl;cout << hash.Find(32) << endl;cout << hash.Find(42) << endl;cout << hash.Find(52) << endl;
}int main()
{TestCloseHash();TestOpenHash();return 0;
}

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

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

相关文章

如何在个人PC的桌面创建一个类似网吧的游戏菜单并分类?

GGTools 免费的桌面图标管理器、软件菜单、游戏菜单 单机版游戏菜单、个人/家用/家庭版游戏菜单、轻量级图标收纳软件

GPT用来润色论文\生成完整长篇论文\进行AI绘图,真的太香了!

详情点击公众号&#xff1a;技术科研吧 链接&#xff1a;GPT用来润色论文\生成完整长篇论文\进行AI绘图&#xff0c;真的太香了&#xff01; 第一&#xff1a;2024年AI领域最新技术 1.OpenAI新模型-GPT-5 2.谷歌新模型-Gemini Ultra 3.Meta新模型-LLama3 4.科大讯飞-星火认…

Jenkins(三):自动化部署SpringBoot项目

前言 在软件开发过程中&#xff0c;自动化部署已经成为不可或缺的一环。Jenkins是一个广泛使用的开源自动化部署工具&#xff0c;它提供了强大的功能和灵活的配置选项&#xff0c;可以帮助开发团队实现高效的持续集成和持续部署。本文将详细介绍如何使用Jenkins自动化部署Spri…

6-树-二叉树的层序遍历 II

这是树的第7篇算法&#xff0c;力扣链接。 给你二叉树的根节点 root &#xff0c;返回其节点值 自底向上的层序遍历 。 &#xff08;即按从叶子节点所在层到根节点所在的层&#xff0c;逐层从左向右遍历&#xff09; 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,nu…

gpt今日最新新闻:gpts的广泛应用

最近&#xff0c;OpenAI给ChatGPT带来了一个备受期待的更新——“GPT提及&#xff08;mentions&#xff09;”功能。这项创新不仅增强了ChatGPT的实用性&#xff0c;也为AI在日常业务中的运用开辟了新路径。在本文中&#xff0c;我将分享我对这项新功能的初步体验&#xff0c;并…

SpringBoot整理-性能优化

Spring Boot性能优化通常涉及到多个方面,包括代码优化、数据库交互、资源使用和系统配置等。下面是一些常见的优化建议: 代码层面的优化:使用合适的数据结构和算法。减少不必要的对象创建,避免内存泄漏。对于重复使用的对象,考虑使用对象池。数据库优化:优化SQL查询,避免复…

前端JavaScript篇之常用的正则表达式有哪些?

目录 常用的正则表达式有哪些&#xff1f; 常用的正则表达式有哪些&#xff1f; 常用的正则表达式包括以下几个方面&#xff1a; 匹配16进制颜色值&#xff1a;#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})可以用于匹配16进制颜色值&#xff0c;如"#ff0000"或"#f00"…

【MySQL】——数据定义

&#x1f383;个人专栏&#xff1a; &#x1f42c; 算法设计与分析&#xff1a;算法设计与分析_IT闫的博客-CSDN博客 &#x1f433;Java基础&#xff1a;Java基础_IT闫的博客-CSDN博客 &#x1f40b;c语言&#xff1a;c语言_IT闫的博客-CSDN博客 &#x1f41f;MySQL&#xff1a…

IDEA插件ChatGPT - Easycode安装使用

IDEA插件ChatGPT - Easycode简介 ChatGPT - Easycode 是一个由 OpenAI 开发的 IntelliJ IDEA 插件,它可以利用 ChatGPT 的强大语言生成能力,帮助开发人员提高编码效率。 主要功能: 代码生成:可以根据自然语言描述生成代码,支持多种编程语言,包括 Java、Python、JavaSc…

【漏洞复现】MDVR数字视频录像机认证绕过漏洞

Nx01 产品简介 MDVR&#xff08;Mobile Digital Video Recorders&#xff09;硬盘录像机是一种使用先进的视音频编解码技术将车内外的视频进行数模转换&#xff0c;进行压缩存储的设备。 Nx02 漏洞描述 阿根廷研究员发现&#xff0c;通过使用“Cookie&#xff1a; uid admin”…

MySQL存储引擎特点一览表——存储引擎如何选择

面试会问嘀嘀嘀 1、MySQL存储引擎特点三大区别已经在下表里面标红 MySQL存储引擎特点 特点InnoDBMyISAMMemory存储限制64TB有有事务安全支持——锁机制行锁表锁表锁Btree索引支持支持支持Hash索引——支持全文索引支持&#xff08;5.6以后&#xff09;支持—空间使用高低N/A内…

深入理解网络通信和TCP/IP协议

目录 计算机网络是什么&#xff1f; 定义和分类 计算机网络发展简史 计算机网络体系结构 OSI 七层模型 TCP/IP 模型 TCP/IP 协议族 TCP/IP 网络传输中的数据 地址和端口号 MAC地址 IP 地址 端口号 为什么端口号有65535个&#xff1f; 综述 TCP 特性 TCP 三次握…

[SWPUCTF 2021 新生赛]Do_you_know_http

我们看到它让我们用WLLM浏览器登录 那我们修改User-Agent的值即可 发现有一个a.php的我们进入该目录 它提示我们不在本地服务器上 发现有一个/secretttt.php的目录 我进入即可获得flag

BUUCTF-Real-[PHPMYADMIN]CVE-2018-12613

目录 漏洞背景介绍 漏洞产生 漏洞利用 漏洞验证 漏洞背景介绍 phpMyAdmin 是一个以PHP为基础&#xff0c;以Web-Base方式架构在网站主机上的MySQL的数据库管理工具&#xff0c;让管理者可用Web接口管理MySQL数据库。借由此Web接口可以成为一个简易方式输入繁杂SQL语法的较佳…

非精线搜索步长规则Armijo规则Goldstein规则Wolfe规则

非精确线搜索步长规则 在数值优化中&#xff0c;线搜索是一种寻找合适步长的策略&#xff0c;以确保在目标函数上获得足够的下降。如最速下降法&#xff0c;拟牛顿法这些常用的优化算法等&#xff0c;其中的线搜索步骤通常使用Armijo规则、Goldstein规则或Wolfe规则等。 设无…

修改MFC图标

摘要&#xff1a;本文主要讲解了MFC程序窗口图标的添加、任务栏、底部托盘的图标添加&#xff0c;以及所生成的exe文件图标的添加。 ​​​​​​​1、在资源视图添加Icon资源 透明图标怎么制作&#xff1f; 1&#xff09;点击图片》右键&#xff1a;使用画图3D进行编辑 2&a…

字节序问题

高低地址与高低字节 高低地址&#xff1a; 最高内存地址 0xFFFFFFFF 栈区&#xff08;从高内存地址&#xff0c;往 低内存地址发展。即栈底在高地址&#xff0c;栈顶在低地址&#xff09; 堆区&#xff08;从低内存地址 &#xff0c;往 高内存地址发展&#xff09; 全局区&…

机器学习周记(第二十八周:文献阅读-GSTPro)2024.1.29~2024.2.4

目录 摘要 ABSTRACT 1 论文信息 1.1 论文标题 1.2 论文摘要 1.3 论文背景 2 论文模型 2.1 问题描述 2.2 总体架构 2.3 动态图神经控制微分方程&#xff08;Dynamic Graph Neural Controlled Differential Equations&#xff09; 2.3.1 空间处理&#xff08;Spatial…

通过手写简易版RPC理解RPC原理

RPC是什么 所谓的RPC其实是为了不同主机的两个进程间通信而产生的&#xff0c;通常不同的主机之间的进程通信&#xff0c;程序编写需要考虑到网络通信的功能&#xff0c;这样程序的编写将会变得复杂。RPC就来解决这一问题的&#xff0c;一台主机上的进程对另外一台主机的进程发…

【实证分析】地级市-资本存量测算结果数据集(含计算公式及原始数据)( 2003-2021年)

该数据为地级市资本存量测算&#xff08;2003-2021年&#xff09;&#xff0c;提供了中国地级市在该期间内资本存量的详细测算结果&#xff0c;包括两种基于2011年和2006年基期的测算方式。该数据集利用了从城市统计年鉴和中国统计年鉴获取的固定资产投资数据及其增速&#xff…