哈希表的实现(哈希捅)

今天是哈希表的实现,哈希表也是一种数据结构,我个人认为还是比较简单的,先给大家看看我 的实现代码吧,如下:

#pragma once
#include <iostream>
#include <set>
#include <map>
#include <vector>
#include <string>
#include <assert.h>
//哈希捅实现哈希表
using namespace std;
namespace cc
{//哈希捅的每个节点template<class K,class V>struct hashnode{pair<K, V> _val;hashnode<K, V>* _next = nullptr;hashnode(const pair<K,V>& x):_val(x){}};//哈希表template<class K, class V>class hash{public:typedef hashnode<K, V> node;hash(){}hash(const hash<K, V>& h){_table.resize(h._table.size(), nullptr);for (size_t i = 0; i < _table.size(); i++){if (h._table[i] != nullptr){node* cur = h._table[i];while (cur){node* copy = new node(cur->_val);copy->_next = _table[i];_table[i] = copy;cur = cur->_next;}}}_size = h._size;}bool insert(const pair<K, V>& x){//如果需要扩容或是此时是一个空表//注意:这里其实有个负荷因子,因为STL中的用哈希桶实现的哈希表中,负荷因子的大小是1,所以就是相等,如果用线性探测或是二次探测//的方法,就不能控制在1,最好控制在0.7-0.8左右就开始扩容,扩容其实根据专业人士的研究,扩容的大小最好是质数的,出现哈希碰撞的几率//就比较少if (_size == _table.size()){vector<node*> tem;tem.resize(_table.size() == 0 ? 10 : _table.size() * 2, nullptr);//旧表节点移动到新表for (size_t i = 0; i < _table.size(); i++){node* cur = _table[i];while (cur){cur->_next = tem[i];tem[i] = cur;cur = cur->_next;}}//移动完成,交换两个表tem.swap(_table);}node* newnode = new node(x);int ret = newnode->_val.first % _table.size();//头插newnode->_next = _table[ret];_table[ret] = newnode;_size++;return true;}node* find(const K& key){int ret = key % _table.size();node* prev = nullptr;node* cur = _table[ret];while (cur){if (cur->_val.first == key)return cur;prev = cur;cur = cur->_next;}return nullptr;}bool erase(const K& key){if (_size == 0){cout << "无法删除空表的内容" << endl;return false;}int ret = key % _table.size();node* prev = nullptr;node* cur = _table[ret];while (cur){if (cur->_val.first == key){if (prev)prev->_next = cur->_next;else_table[ret] = cur->_next;delete cur;_size--;return true;}prev = cur;cur = cur->_next;}return false;}private:size_t _size = 0;vector<node*> _table;};
}

上面就是我用哈希捅实现的哈希表,思维逻辑还是比较简单的,但是还是要注意的点。

先来说说哈希表的作用吧。我个人感觉哈希表就是寻找方便,时间复杂度是O(1),个人认为这应该是查找的天花板了吧,就连各种效率都很优的AVL树和红黑树都是log(n),所以个人认为这个数据结构应该是查找的天花板了,但是他的缺点也很明显。我们先来看看下面的图,来看看他的原理:

如上,它的原理其实就是这样的,而哈希捅的实现其实使用链表来实现的,也就是每个桶都挂了一个单向链表,其实不仅可以挂单向链表,双向链表其实也可以挂,但是不用双向链表的原因是,双向链表比单链表的消耗大,所以才用的单链表,而在同一个桶的位置,挂数的时候,我们普遍用头插,这个就不说了,很容易理解,头插的时间复杂度是O(1)。

其实很多人在看到这种情况的时候,可能会懵,这中结构怎么查找的时间复杂度是O(1)呢?如果我查找的桶刚好是一个挂的非常多的,这不是就相当于O(N)了嘛,其实这个我刚开始也有这种疑惑,但是到现在我就比较释然了,我们打个比喻,最坏的情况是所有插入的数在一个桶的位置,这个是最坏的情况,但是不知道大家测试过吗?这种情况除非是人为的,也就是自己故意的,不然基本是不会出现的,因为我测试过,插入随机的十万个左右的树,它的桶数是大概好像是十二万多,而每个桶所挂起的数,最多的才是3个,普遍都是一个桶挂一个数,所以你担心的情况所出现的概率是非常低的。几乎没有,除非你是自己故意的。所以他的每个桶所挂起的数,基本是常数级别的,所以就是O(1),如果你实现是担心,其实他的每个桶的位置不一定要挂链表,也可以挂红黑树啊,这样效率不就是越来越高了嘛,所以我们不要看到一点点的缺点就不放过,而且他的这个缺点出现的概率实在是太低太低了。

我们可以看到的是,它的查找效率几乎是无敌的,因为不管查找什么,他都是映射的关系,直接映射到它的桶的位置,但是其实他的缺点也非常的大,它的缺点就是扩容的消耗太大了,因为他扩容还要把所有的数据再给新扩的这个表拷贝一份,所以这个是他的缺点。

还有就是线性探测与二次探测的方法来实现哈希表,这个后面会陆续的发。

本篇内容如果对你有用的话,希望带你一下赞吧!!!

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

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

相关文章

MySQL主从分离读写复制

在高负载的生产环境里&#xff0c;把数据库进行读写分离&#xff0c;能显著提高系统的性能。下面对MySQL的进行读写分离。 试验环境 A机&#xff1a;IP:192.168.0.1 mysql版本&#xff1a;mysql-5.6.4,主数据服务器&#xff08;只写操作&#xff09; B机&#xff1a;IP:192.…

网管实战⑼:配置华为S5720交换机

配置好汇聚交换机后&#xff0c;需要根据单位情况配置具体的接入交换机。 自从2019年12月底配置好交换机后&#xff0c;基本上都没有怎么操作交换机了。那时候使用的是H3C交换机&#xff0c;主要是H3C S7706、H3C S5120、H3C S5130、H3C S5500、H3C S3600等型号的交换机&#x…

Kafka3.0.0版本——消费者(自动提交 offset)

目录 一、自动提交offset的相关参数二、消费者&#xff08;自动提交 offset&#xff09;代码示例 一、自动提交offset的相关参数 官网文档 参数解释 参数描述enable.auto.commi默认值为 true&#xff0c;消费者会自动周期性地向服务器提交偏移量。auto.commit.interval.ms如果…

Ubuntu终端指令

目录 目录 一、基本指令 1.命令行提示符 2.切换用户 3.修改密码 4.查看当前目录下的文件 5.修改文件权限---chmod 6.cd 切换路径 7.touch 8.cat 9.echo 10.mkdir 11. rm/rmdir 二、在线下载软件 1.更新软件源 2.更新软件列表 3.下载软件 三、离线安装软件 1. …

车载软件架构——基础软件供应商开发工具链(一)

车载软件架构——基础软件供应商&开发工具链(一) 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 没有人关注你。也无需有人关注你。你必须承认自己的价值,你不能站在他人的角度来反对自己…

Qt包含文件不存在问题解决 QNetworkAccessManager

这里用到了Qt的网络模块&#xff0c;在.pro中添加了 QT network 但是添加 #include <QNetworkAccessManager> 会报错说找不到&#xff0c;可以通过在项目上右键执行qmake后&#xff0c;直接#include <QNetworkAccessManager>就不会报错了&#xff1a;

MLC-LLM 部署RWKV World系列模型实战(3B模型Mac M2解码可达26tokens/s)

0x0. 前言 我的 ChatRWKV 学习笔记和使用指南 这篇文章是学习RWKV的第一步&#xff0c;然后学习了一下之后决定自己应该做一些什么。所以就在RWKV社区看到了这个将RWKV World系列模型通过MLC-LLM部署在各种硬件平台的需求&#xff0c;然后我就开始了解MLC-LLM的编译部署流程和…

搭建自己的OCR服务,第一步:选择合适的开源OCR项目

一、OCR是什么&#xff1f; 光学字符识别&#xff08;Optical Character Recognition, OCR&#xff09;是指对文本资料的图像文件进行分析识别处理&#xff0c;获取文字及版面信息的过程。 亦即将图像中的文字进行识别&#xff0c;并以文本的形式返回。 二、OCR的基本流程 1…

实战教程:如何将自己的Python包发布到PyPI上

1. PyPi的用途 Python中我们经常会用到第三方的包&#xff0c;默认情况下&#xff0c;用到的第三方工具包基本都是从Pypi.org里面下载。 我们举个栗子: 如果你希望用Python实现一个金融量化分析工具&#xff0c;目前比较好用的金融数据来源是 Yahoo 和 Google。你可能需要读取…

3dMax全球学习资源、资源文件和教程 !

此样例教育教程和学习资源旨在提供使用Autodesk 3ds Max时的计划知识和培训、正确的工作流、流程管理和最佳实践。 您在Autodesk三维设计领域的职业生涯 有关使用3ds Max和Maya在计算机图形领域开始职业生涯的提示&#xff08;包括新的3ds Max和Maya介绍教程&#xff0c;以复…

Spring Cloud:构建微服务的最佳实践

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

PLC编码器测速(限幅滤波+中心差分法求导SCL源代码)

M法测速的基本原理,大家可以查看专栏的系列文章,这里不再赘述常用链接如下: PLC通过编码器反馈值计算速度的推荐做法(算法解析+ST代码)_编码器脉冲怎么转换为速度_RXXW_Dor的博客-CSDN博客PLC如何测量采集编码器的位置数据,不清楚的可以参看我的另一篇博文:三菱FX3U PLC…

C#模拟PLC设备运行

涉及&#xff1a;控件数据绑定&#xff0c;动画效果 using System; using System.Windows.Forms;namespace PLCUI {public partial class MainForm : Form{ public MainForm(){InitializeComponent();}private void MainForm_Load(object sender, EventArgs e){// 方式2&#x…

索尼 toio™ 应用创意开发征文|探索创新的玩乐世界——索尼 toio™

导语&#xff1a; 在技术的不断进步和发展中&#xff0c;玩具也逐渐融入了智能化的潮流。索尼 toio™作为一款前沿的智能玩具&#xff0c;给孩子和成人带来了全新的游戏体验。本文将介绍索尼 toio™的特点、功能和应用场景&#xff0c;让读者了解这个令人兴奋的创新产品。 1. 了…

《Go语言在微服务中的崛起:为什么Go是下一个后端之星?》

&#x1f337;&#x1f341; 博主猫头虎&#x1f405;&#x1f43e; 带您进入 Golang 语言的新世界✨✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文并茂&#x1f…

【Unity的HDRP下ShaderGraph实现权重缩放全息投影_(内附源码)】

实现权重缩放全息投影 效果如下 效果如下 顶点位置偏移 链接&#xff1a; 提取码&#xff1a;1234

Axure RP仿QQ音乐app高保真原型图交互模板源文件

Axure RP仿QQ音乐app高保真原型图交互模板源文件。本套素材模板的机型选择华为的mate30&#xff0c;在尺寸和风格方面&#xff0c;采用标准化制作方案&#xff0c;这样做出来的原型图模板显示效果非常优秀。 原型中使用大量的动态面板、中继器、母版&#xff0c;涵盖Axure中技…

YAML配置文件

YAML配置文件 SpringBoot中application.properties文件存在的问题&#xff1a;配置太多后难阅读和修改&#xff0c;层级结构辨识度不高。 简介 YAML是"YAML Ain’t a Markup Language"&#xff08;YAML不是一种标记语言&#xff09;的递归缩写。在开发的这种语言时&a…

Matlab信号处理3:fft(快速傅里叶变换)标准使用方式

Fs 1000; % 采样频率 T 1/Fs; % 采样周期&#xff1a;0.001s L 1500; % 信号长度 t (0:L-1)*T; % 时间向量. 时间向量从0开始递增&#xff0c;0s~1.499sS 0.7*sin(2*pi*50*t) sin(2*pi*120*t); % 模拟原信号 X S 2*randn(size(t)); …