【C++】哈希一

这篇博客要说的是哈希算法哈希又称为散列,它是将存储的和存储的位置建立起关联关系的一种算法,或者说是一种任意长度的数据映射为固定长度的输出的算法

什么意思呢?我们来看一个例子:比如说我们要存储1,2,3,4,5,6这几个数据,我们可以开6个空间大小的数组用于存储,正好下标(位置)跟数据(值)之间是有一定的关系的,很容易存储。

但是假如是下面6个数据呢?1,2,3,1000,1001,1002难道我们还要开1000个空间不成?当然不可以,这太浪费了,于是就开始想办法,让它们都对于总个数6取余不就得到范围比较小的值了吗。它们取余后分别得到1,2,3,4,5,0,我们让这几个数据当作它们各自的位置,这样每一个数据都和一个位置相互对应了,这就是一种解决问题的方法。

上面两个例子已经很形象的说明了什么是哈希,并且第一个例子就是我们的直接定址法,第二个例子就是除留余数法

但是我们的除留余数法还是有问题的,有没有可能两个数取余后得到的数相同?肯定是有可能的,这种情况就叫哈希冲突。我们可以知道,哈希冲突越多,那么效率就越低。所以我们一般当负载因子或者叫载荷因子就是实际存的数据个数除以表的大小)大于某个数就要扩容,增大表的大小。这样就可以一定程度的保证效率。那么接下来我们就要解决哈希冲突,有两种方法,一种叫闭散列开放定址法,一种叫开散列拉链法,也叫哈希桶

它们分别是什么意思呢?下面我们分别来说,闭散列开放定址法就是在这个固定长度的数组中如果一个值要放的位置已经有其他的值了,那么就从这个位置向后边找,直到找到空的位置放入,如果找到结尾,那么再返回头去找。这个向后边找可以一个一个找,就叫线性探测,也可以1,4,9,16.....这样二次方数这样找,就叫做二次探测

下面一个是哈希桶也叫开散列拉链法,就是我们在哈希表中存某个数据所在节点的指针,如果下个数据仍然在这个位置,那么就挂在上个数据的下边就可以了,挂上数据之后就像一个桶或者像拉链,于是名字由此得名

那么接下来我们就分别用这两种解决哈希冲突的方法来实现一下哈希表,这里我们的哈希表中的值先按整形看,等后边我们再慢慢加上模板等一系列东西,先看第一种方法

enum state {EMPTY,EXIST,DELETE
};
struct HashNode {int val=0;state state=EMPTY;
};
class HashTable {
public:HashTable(size_t n = 10) {_hashvec.resize(n);}HashNode* find(size_t key) {int hashi = key % _hashvec.size();while (_hashvec[hashi].state != EMPTY && _hashvec[hashi].val != key) {hashi++;hashi %= _hashvec.size();}if (_hashvec[hashi].state == EMPTY)return nullptr;return &_hashvec[hashi];}bool insert(size_t data) {if (find(data))return false;if (_n * 10 / _hashvec.size() >= 7) {//扩容HashTable newtable;newtable._hashvec.resize(_hashvec.size()*2);for (size_t i = 0; i < _hashvec.size(); i++) {if(_hashvec[i].state==EXIST)newtable.insert(_hashvec[i].val);}_hashvec.swap(newtable._hashvec);}size_t hashi = data % _hashvec.size();while (_hashvec[hashi].state == EXIST) {hashi++;hashi %= _hashvec.size();}_hashvec[hashi].val = data;_hashvec[hashi].state = EXIST;_n++;return true;}bool erase(size_t data) {HashNode* tmp = find(data);if (tmp == nullptr)return false;tmp->state = DELETE;--_n;return true;}
private:size_t _n=0;vector<HashNode> _hashvec;
};

再看第二种方法

struct HashNode {HashNode(size_t n=0):val(n),_next(nullptr){}size_t val = 0;HashNode* _next = nullptr;};class HashTable {public:HashTable(size_t n=10) {_hashvec.resize(n, nullptr);}HashNode* find(size_t key) {size_t hashi = key % _hashvec.size();HashNode* cur = _hashvec[hashi];while (cur) {if (cur->val == key)return cur;cur = cur->_next;}return nullptr;}bool insert(size_t key) {if (find(key))return false;if (_n == _hashvec.size()) {//扩容HashTable newtable(_hashvec.size() * 2);for (size_t i = 0; i < _hashvec.size(); i++) {HashNode* cur = _hashvec[i];HashNode* next = nullptr;while (cur) {next = cur->_next;size_t hashi = cur->val % newtable._hashvec.size();cur->_next = newtable._hashvec[hashi];newtable._hashvec[hashi] = cur;/*if (newtable._hashvec[hashi] == nullptr) {newtable._hashvec[hashi] = cur;}else {HashNode* tmp = newtable._hashvec[hashi];while (tmp->_next) {tmp = tmp->_next;}tmp->_next = cur;}cur->_next = nullptr;*/cur = next;}_hashvec[i] = nullptr;}_hashvec.swap(newtable._hashvec);}size_t hashi = key % _hashvec.size();HashNode* newnode = new HashNode(key);newnode->_next = _hashvec[hashi];_hashvec[hashi] = newnode;++_n;return true;}bool erase(size_t key) {size_t hashi = key % _hashvec.size();HashNode* prev = nullptr;HashNode* cur = _hashvec[hashi];while (cur&&cur->val != key) {prev = cur;cur = cur->_next;}if (cur == nullptr)return false;if (prev == nullptr) {_hashvec[hashi] = cur->_next;}else {prev->_next = cur->_next;}delete cur;return true;}private:size_t _n = 0;vector<HashNode*> _hashvec;};
}

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

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

相关文章

kkFileView基于pdf.js实现多词高亮

参考文档&#xff1a; 1.文件文档在线预览转换解决方案和应用 2.kkfileview预览pdf格式文件&#xff0c;实现多关键词高亮和定位_kkfileview高亮方案-CSDN博客 3.PDF.js实现搜索多个不同的关键词高亮显示效果 最终效果&#xff1a; 需求描述&#xff1a; 预览文件时&#xff0…

免费SSL证书和付费SSL证书的区别和申请

免费SSL证书和付费SSL证书的区别点还是比较多的。对来说免费证书适用的环境会单一一些&#xff0c;一般使用免费证书的环境都是个人门户网站或者是小微企业的门户官网&#xff08;无隐私信息&#xff09;。受免费证书安全等级以及安全性的限制影响&#xff0c;如果是为了自身网…

如何利用纯前端技术,实现一个网页版视频编辑器?

纯网页版视频编辑器 一、前言二、功能实现三、所需技术四、部分功能实现4.1 素材预设4.2 多轨道剪辑 一、前言 介绍&#xff1a;本篇文章打算利用纯前端的技术&#xff0c;来实现一个网页版的视频编辑器。为什么突然想做一个这么项目来呢&#xff0c;主要是最近一直在利用手机…

ssm 体检预约管理系统开发mysql数据库web结构java编程计算机网页源码eclipse项目

一、源码特点 ssm 体检预约管理系统是一套完善的信息系统&#xff0c;结合springMVC框架完成本系统&#xff0c;对理解JSP java编程开发语言有帮助系统采用SSM框架&#xff08;MVC模式开发&#xff09;&#xff0c;系统具有完整的源代码和数据库&#xff0c; 系统主要采用B/S…

快速删除node_modules依赖包的命令rimraf

1、安装rimraf npm install -g rimraf 2、使用命令删除node_modules rimraf node_modules *** window系统&#xff0c;使用命令很快就删除node_modules ***

RabbitMQ交换机的类型

交换机类型 可以看到&#xff0c;在订阅模型中&#xff0c;多了一个exchange角色&#xff0c;而且过程略有变化&#xff1a; Publisher&#xff1a;生产者&#xff0c;不再发送消息到队列中&#xff0c;而是发给交换机 Exchange&#xff1a;交换机&#xff0c;一方面&#xff…

JVM常见面试题

1. 什么是JVM JVM指的是Java虚拟机&#xff0c;本质上是一个运行在计算机上的程序&#xff0c;他的职责是运行Java字节码文件&#xff0c;作用是为了支持跨平台特性JVM的功能有三项&#xff1a;第一是解释执行字节码指令&#xff1b;第二是管理内存中对象的分配&#xff0c;完…

NetworkX、igraph、Gephi三大主流复杂网络建模与分析工具有什么区别?

★ 导言 ★ 本期给大家介绍NetworkX、igraph、Gephi三大主流复杂网络建模与分析工具的功能,并给出它们之间的区别与联系。 ★ 正文 ★ 正文开始之前,先附上三个工具的官方网址: NetworkX:https://networkx.org/ igraph:https://igraph.org/ Gephi:

eclipse中tomcat环境配置,2024年最新Web前端面试选择题

先自我介绍一下&#xff0c;小编浙江大学毕业&#xff0c;去过华为、字节跳动等大厂&#xff0c;目前阿里P7 深知大多数程序员&#xff0c;想要提升技能&#xff0c;往往是自己摸索成长&#xff0c;但自己不成体系的自学效果低效又漫长&#xff0c;而且极易碰到天花板技术停滞…

ChatGPT实用指南2024

随着ChatGPT技术的演进&#xff0c;越来越多的人开始在工作中利用此工具。以下是关于ChatGPT的实用指南&#xff0c;适合不太熟悉此技术的朋友参考。 一、ChatGPT概述 1. ChatGPT是什么&#xff1f; ChatGPT是基于OpenAI开发的GPT大型语言模型的智能对话工具。它能够通过自然语…

# RAG | Langchain # Langchain RAG:打造Markdown文件的结构化分割解决方案

【文章简介】 在信息技术的现代背景下&#xff0c;高效地处理和分析文本数据对于知识获取和决策支持至关重要。Markdown文件因其易读性和高效性&#xff0c;在文档编写和知识共享中占据了重要地位。然而&#xff0c;传统的文本处理方法往往忽视了Markdown的结构化特性&#xff…