哈希表的实现(哈希捅)

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

#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,一经查实,立即删除!

相关文章

TCP、UDP 协议的区别,各自的应用场景

分析&回答 TCP 传输控制协议,提供的是面向连接、可靠的字节流服务。当客户和服务器彼此交换数据前&#xff0c;必须先在双方之间建立一个TCP连接&#xff0c;之后才能传输数据。TCP提供超时重发&#xff0c;丢弃重复数据&#xff0c;检验数据&#xff0c;流量控制等功能&…

LeetCode-93-复原IP地址

题目描述&#xff1a;有效 IP 地址 正好由四个整数&#xff08;每个整数位于 0 到 255 之间组成&#xff0c;且不能含有前导 0&#xff09;&#xff0c;整数之间用 ‘.’ 分隔。 例如&#xff1a;“0.1.2.201” 和 “192.168.1.1” 是 有效 IP 地址&#xff0c;但是 “0.011.25…

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…

c3p0、dbcp、proxool、BoneCP比较

1.1 测试环境: 操作系统&#xff1a;windows xp sp3数据库&#xff1a;mysql 5.1 1.2 测试条件&#xff1a; initialSize30; maxSize200; minSize30; 其余参数为默认值&#xff1b; 1.3 测试代码&#xff1a; 利用JAVA代码模拟多线程对这三种数据库连接池进行测试&#xf…

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. …

Day61:代码随想录结束打卡~

大体感受 为期60的算法训练营结束了&#xff0c;这钱其实挺值的&#xff0c;人就是这样&#xff0c;一旦你有点付出才会懂得珍惜。 最大的收获就是见识到了人有决心有多可怕&#xff0c;这60天如果让我自己刷&#xff0c;其实根本坚持不了几天&#xff0c;但是现在证明我确实坚…

大数据(八):Pandas的基础应用详解(五)

专栏介绍 结合自身经验和内部资料总结的Python教程,每天3-5章,最短1个月就能全方位的完成Python的学习并进行实战开发,学完了定能成为大佬!加油吧!卷起来! 全部文章请访问专栏:《Python全栈教程(0基础)》 再推荐一下最近热更的:《大厂测试高频面试题详解》 该专栏对…

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

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

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

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

在h5中使用 JavaScript 和 HTML DOM 对表格的表头进行排序的解决方案

在 HTML5 (h5) 中&#xff0c;可以使用 JavaScript 和 HTML DOM 来对表格的表头进行排序。以下是一个简单的示例&#xff0c;使用纯 JavaScript 实现&#xff1a; 首先&#xff0c;在 HTML 中创建一个带有表头的表格&#xff1a; <table id"myTable"><the…

P1294 高手去散步

高手去散步 - 洛谷 题解&#xff1a; 可能走到一半就走完了&#xff0c;注意递归结束条件 #include<bits/stdc.h> using namespace std; const int N110; int n,m,flag; int e[N],ne[N],h[N],w[N],idx; int st[N]; int ans-1e13; void add(int a,int b,int c) {e[idx]…

【Linux之进程间通信】09.有名管道和无名管道(补充)

有名管道最大的特点&#xff08;为什么要有无名管道和有名管道&#xff1f;&#xff09; 有名管道是真实存在的一个特殊文件&#xff0c;所以当进程退出后&#xff0c;管道文件还在&#xff0c;有名管道文件将继续保存在文件系统中以便以后使用&#xff0c;其他进程仍然可以读写…

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…

dubbo和feign那个效率高呢?

Dubbo 和 Feign 都是常用的远程服务调用框架&#xff0c;它们在不同的应用场景下具有各自的优势。效率高与否取决于具体的使用情况和需求。 Dubbo&#xff1a;Dubbo 是一款高性能的分布式服务框架&#xff0c;主要面向大规模的微服务架构。Dubbo 在性能方面表现出色&#xff0c…

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

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

Electron 两个线程

Electron&#xff1a;它允许使用最初为Web应用程序开发的前端和后端组件开发桌面GUI应用程序&#xff1a;后端的Node.js运行时和前端的Chromium。 每个Electron应用都有两个线程&#xff1a;一个是主线程&#xff08;处理应用窗口和启动&#xff09;&#xff0c;另一个是渲染线…

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

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