哈希表的实现(1)----除留余数法实现

一,哈希表的介绍

 哈希表是一种通过哈希思想实现的一种数据结构。哈希表这种数据结构的特点便是可以通过一个值快速的定位这个值所在的位置实现插入,删除,查找。在这篇博客里面,我们便来实现一个通过除留余数法实现的一个哈希表。

二,哈希表的实现

1,哈希表的结构

因为这里要实现的是一个除留余数法实现的一个哈希表,所以是要用到线性探测的方法的。所以在哈希表内部的成员里便要一个连续的存储结构,所以便可以用一个vector<>

vector里面的元素该用什么类型呢?因为要实现一个比较漂亮的哈希表,所以这个哈希表里面的元素最好能够表示当前的状态,所以这里我们得自己定义hashData。还有为了方便的统计哈希表里面的元素个数,我们又得定义一个_n表示哈希表里面的元素个数。

结构定义如下:

	enum State{EMPTY,//代表空状态EXIST,//代表存在状态DELETE//代表删除状态};template<class K,class V>struct hashData{State _st;//状态pair<K, V>_kv;//元素数据};template<class K,class V>class HashTable{private:vector<hashData<K, V>> _hashtables;size_t _n = 0;//表示元素个数,并且要初始化,并且一定得是size_t类型的变量(预防插入一个关键值为负数的元素)};

二,插入操作实现

插入操作的实现的实现主要分为以下几步:

1,计算插入值对应的位置。

2,如果这个位置上面已经有元素了便要往后线性探测。(这里便是出现了哈希冲突)

3,如果插入的元素已经把表给填满了便要开新表,然后将旧表中的值重新映射填入到新表中。然后再交换给旧表。

插入操作优化的点:

在插入时最讨厌的便是出现哈希冲突,所以为了减少哈希冲突的出现便可以在定义一个叫做负载因子。一般负载因子的值达到了0.7便要开始扩容。

代码实现如下:

bool Insert(const pair<K, V>key){if (_n * 10 / _hashtables.size() == 7){int newsize = 2 * _hashtables.size();HashTable<K,V>newHash;for (int i = 0;i < _hashtables.size();i++){if (_hashtables[i]._st == EXIST){newHash.Insert(_hashtables[i]._kv);}}_hashtables.swap(newHash._hashtables);}int hashi = key.first % _hashtables.size();while (_hashtables[hashi]._st == EXIST){hashi++;hashi %= _hashtables.size();}_hashtables[hashi]._kv = key;_hashtables[hashi]._st = EXIST;_n++;return true;}

三,查找操作

哈希表的查找操作步骤如下:

1,通过除留余数法计算出hashi。

2,通过hashi定位到指定位置,如果这个指定位置的状态是EMPTY便停止。反之便继续找。

3,找到了便将该位置返回。

4,找不到便返回一个nullptr。

实现代码如下:

hashData<K, V>* Find(const pair<K, V>key){size_t hashi = key .first% _hashtables.size();while (_hashtables[hashi]._st != EMPTY){if (_hashtables[hashi]._st == EXIST&&_hashtables[hashi]._kv == key){return &_hashtables[hashi];}hashi++;hashi %= _hashtables.size();}return nullptr;}

在实现了查找操作以后便可以在插入操作里面实现一个不能插入相同元素的功能。代码如下:

if (Find(key))
{return false;
}

四,删除操作

这里的删除操作实现的是一种伪删除法。删除时通过Find()找到对应的值,然后将这个值对应的状态改为DELETE即可。

代码:

bool Erase(const pair<K, V>key)
{hashData<K, V>* ret = Find(key);if (ret){ret->_st = DELETE;return true;}return false;
}

五,全部代码

#include<iostream>
#include<vector>
using namespace std;namespace Hash
{enum State{EMPTY,//代表空状态EXIST,//代表存在状态DELETE//代表删除状态};template<class K,class V>struct hashData{State _st;//状态pair<K, V>_kv;//元素数据};template<class K,class V>class HashTable{public:HashTable(){_hashtables.resize(10);}bool Insert(const pair<K, V>key){if (Find(key)){return false;}if (_n * 10 / _hashtables.size() == 7){int newsize = 2 * _hashtables.size();HashTable<K,V>newHash;for (int i = 0;i < _hashtables.size();i++){if (_hashtables[i]._st == EXIST){newHash.Insert(_hashtables[i]._kv);}}_hashtables.swap(newHash._hashtables);}int hashi = key.first % _hashtables.size();while (_hashtables[hashi]._st == EXIST){hashi++;hashi %= _hashtables.size();}_hashtables[hashi]._kv = key;_hashtables[hashi]._st = EXIST;_n++;return true;}hashData<K, V>* Find(const pair<K, V>key){size_t hashi = key .first% _hashtables.size();while (_hashtables[hashi]._st != EMPTY){if (_hashtables[hashi]._st == EXIST&&_hashtables[hashi]._kv == key){return &_hashtables[hashi];}hashi++;hashi %= _hashtables.size();}return nullptr;}bool Erase(const pair<K, V>key){hashData<K, V>* ret = Find(key);if (ret){ret->_st = DELETE;return true;}return false;}void Print(){for (int i = 0;i < _hashtables.size();i++){if (_hashtables[i]._st == EXIST){printf("->%d\n",_hashtables[i]._kv.second);}else if (_hashtables[i]._st == DELETE){printf("%d->D\n", _hashtables[i]._kv.second);}else{printf("-> \n");}}}private:vector<hashData<K, V>> _hashtables;size_t _n = 0;//表示元素个数,并且要初始化};void HT1(){HashTable<int, int>hash;hash.Insert(make_pair<int, int>(1, 1));hash.Insert(make_pair<int, int>(1, 8));hash.Insert(make_pair<int, int>(1, 9));hash.Insert(make_pair<int, int>(1, 12));hash.Insert(make_pair<int, int>(1, 12));hash.Insert(make_pair<int, int>(1, 19));hash.Insert(make_pair<int, int>(1, 10));hash.Insert(make_pair<int, int>(1, 20));hash.Erase(make_pair<int, int>(1, 10));hash.Insert(make_pair<int, int>(1, 30));hash.Print();}}

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

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

相关文章

大模型学习与实践笔记(二)

一、代码仓库&#xff1a; InternLM: https://github.com/InternLM/InternLM/ 课程讲师&#xff1a;宋志学大佬&#xff0c;d2l-ai-solutions-manual 开源项目负责人 二、Lagent框架 三、基于InternLM的智能对话 3.1 环境配置&#xff1a; cuda11.7 pytorch2.0.1 其他环境…

Python如何免费调用微软Bing翻译API

一、引言 现在免费的机器翻译越来越少了&#xff0c;随着有道翻译开始收费&#xff0c;百度降低用户的免费机器翻译额度(目前只有实名认证过的高级用户才能获得100万字符的免费翻译额度)&#xff0c;而亚马逊、腾讯等机器翻译调用相对比较麻烦&#xff0c;需要下载各种插件包&…

软件项目质量保证措施-word

一、 质量保障措施 二、 项目质量管理保障措施 &#xff08;一&#xff09; 资深的质量经理与质保组 &#xff08;二&#xff09; 全程参与的质量经理 &#xff08;三&#xff09; 合理的质量控制流程 1&#xff0e; 质量管理规范&#xff1a; 2&#xff0e; 加强协调管理&…

【python】07.字符串和常用数据结构

字符串和常用数据结构 使用字符串 第二次世界大战促使了现代电子计算机的诞生&#xff0c;最初计算机被应用于导弹弹道的计算&#xff0c;而在计算机诞生后的很多年时间里&#xff0c;计算机处理的信息基本上都是数值型的信息。世界上的第一台电子计算机叫ENIAC&#xff08;电…

【纯CSS特效源码】(一)几款漂亮的文字特效

1.渐变文字 使用background: -webkit-linear-gradient(#d8ecec, #2d888b);定义背景渐变色 并使用-webkit-text-fill-color: transparent;指定了文本字符的填充颜色 <!DOCTYPE html> <html><style>body {background-color: #111;}#content {position: abso…

大小鼠”专项”训练实验跑台—ZL-013小动物实验跑步机

运动疲劳的研究一直备受研究学者的关注&#xff0c;运动性疲劳动物模型也已经成为运动性疲劳研究的重要途径。运动性疲劳与一般的疲劳不同&#xff0c;其是在运动过程中发生的一种疲劳症候&#xff0c;不同的运动方式对疲劳产生的程度不同&#xff0c;对动物机体产生的影响也大…

C++力扣题目617--合并二叉树

给你两棵二叉树&#xff1a; root1 和 root2 。 想象一下&#xff0c;当你将其中一棵覆盖到另一棵之上时&#xff0c;两棵树上的一些节点将会重叠&#xff08;而另一些不会&#xff09;。你需要将这两棵树合并成一棵新二叉树。合并的规则是&#xff1a;如果两个节点重叠&#…

小程序中滚动字幕

需求&#xff1a;在录像时需要在屏幕上提示字幕&#xff0c;整体匀速向上滚动 html部分&#xff1a; <view class"subtitles_main"><view style"font-size:34rpx;color: #fff;line-height: 60rpx;" animation"{{animation}}">人生的…

腾讯云添加SSL证书

一、进入腾讯云SSL证书&#xff1a; ssl证书控制台地址 选择“我的证书”&#xff0c;点击"申请免费证书" 2、填写域名和邮箱&#xff0c;点击“提交申请” 在此页面中会出现主机记录和记录值。 2、进入云解析 DNS&#xff1a;云解析DNS地址 进入我的解析-记录…

步进电机相关知识 以及 TMC2660 步进电机驱动芯片驱动步进电机

步进电机相关知识 以及 TMC2660 步进电机驱动芯片驱动步进电机 前言一、步进电机基础知识1、电机常用概念2、步进电机小知识3、步进电机分类4、步进电机工作原理细分驱动步进电机 5、使用的步进电机型号以及相关参数 二、步进电机驱动芯片 TMC2660 和MCU端步进电机驱动芯片TMC2…

js中try...catch捕捉错误

文章目录 一、前言二、场景2.1、setTimeout2.2、Promise 三、最后 一、前言 说到try...catch都觉得非常熟悉了&#xff0c;不就是用来捕捉代码块中的错误嘛&#xff0c;平时也用得比较多的 二、场景 try...catch只能捕捉到同步执行代码块中的错误 2.1、setTimeout try {setT…

Surface mesh结构学习

CGAL 5.6 - Surface Mesh: User Manual Surface_mesh 类是半边数据结构的实现&#xff0c;可用来表示多面体表面。它是半边数据结构&#xff08;Halfedge Data Structures&#xff09;和三维多面体表面&#xff08;3D Polyhedral Surface&#xff09;这两个 CGAL 软件包的替代品…