数据结构与算法C++实现(10)之哈希表

2023-11-06

一、概念


散列技术是在记录的存储位置和他的关键字之间建立一个确定的对应关系f,是的每个关键字key对应一个存储位置f(key)。查找时,根据这个对应的关系找到给定值key的映射f(key),若查找集合中存在这个记录,则必定在f(key)的位置上。我们把这种对应关系f成为散列函数,又称为哈希(Hash)函数。采用散列技术将记录存储在一块连续的存储空间中,这块连续空间称为散列表或哈希表(Hash-Table)。

二、散列表的构造方法


2.1 直接定址法
直接定址法使用下面的公式


f(key)=a×key+b,b为常数
 

比如统计出生年份,那么就可以使用f(key)=key−1990 f(key) = key-1990f(key)=key−1990来计算散列地址。


2.2 除留取余法
这种方法是最常用的散列函数构造方法,对于表长为m的散列公式为
 

这里的mod是取余的意思

 

2.3 数字分析法
分析数字关键字在各位上的变化情况,取比较随机的位作为散列地址这里使用一个手机号码作为例子,手机号码是一个字符串,一般的说,后面4位是真正的用户号。


2.4 折叠法
把关键词分割成位数相同的几个部分,然后叠加。


2.5 平方取中法

三、冲突解决方法

常用处理冲突的思路:

  • 换个位置: 开放地址法
  • 同一位置的冲突对象组织在一起: 链地址法

开放地址其实是一种治标不治本的方法,因此我们这里只介绍链地址法。

从图中可以看出,哈希表的每个地址中存的是一个链表的地址,地址冲突的元素,都放在这个链表中,这样就不用担心地址冲突啦!

代码:

#include<iostream>
#include<list>
#include<vector>
using namespace std;

template<class T>
class Hash
{
	public:
		Hash(int num = 53) : tables(num, nullptr){ }
		unsigned int HashFunction(const T& item) // 产生哈希数 
		{
			unsigned result = 0;
			char* new_ptr = (char*)(&item);//强行转换为字符指针,为了下面的for循环中 
			for(int i = 0; i < sizeof(item); ++i)//一个字节一个字节的产生独有的哈希数 
			{
				result += new_ptr[i] * 3 + 5;//可以设计成自己喜欢的方程,来产生哈系数 
			}
			return result;
		}
		void Push(const T& item)
		{
			unsigned int hash_num = HashFunction(item);
			hash_num = hash_num % tables.size();//取余,将哈系数控制在我们的索引之内 
			if(tables[hash_num] == nullptr)
			{
				tables[hash_num] = new list<T>;
				(*tables[hash_num]).push_back(item);
			}
			else
			{
				(*tables[hash_num]).push_back(item);
			}
		}
		void Delete(const T& item)
		{
			unsigned int hash_num = HashFunction(item);
			hash_num = hash_num % tables.size();
			if(tables[hash_num] == nullptr)
			{
				return;
			}
			else
			{
				(*tables[hash_num]).remove(item);
			}
			
			if((*tables[hash_num]).size() == 0)//如果链表为空,就将这个链表delete 
			{
				delete tables[hash_num];
				tables[hash_num] = nullptr;
			}
		} 
	private:
		vector<list<T>*> tables; 	
};


int main()
{
	Hash<int> my_hash_table;
	for(int i = 0; i < 10; ++i)
	{
		my_hash_table.Push(i*6);
	} 
	
	my_hash_table.Delete(6);
	
	
	return 0;
}

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

数据结构与算法C++实现(10)之哈希表 的相关文章

  • 【数据结构】循环队列的实现(附带详细注释)

    前言 数据结构系列首页 是数据结构系列文章的首页 其中会逐步更新各种数据结构的实现 有兴趣的选手可以一看 首页中不仅有各种数据结构的实现 还有学习数据结构必备的基础知识 如果有选手觉得自己的基础不太牢固 可以先将搞定基础知识 之后再攻克数据
  • 剑指 Offer 68 - I. 二叉搜索树的最近公共祖先 -- 递归

    0 题目描述 leetcode原题链接 剑指 Offer 68 I 二叉搜索树的最近公共祖先 1 递归解法 终止条件 当 root 为空时 返回 None 当 p q 都在 root 的右子树中 则开启递归 root right 并返回 否
  • 企业大数据CDH集群安全----sentry

    Sentry安装 1 cm中选择添加服务 选择sentry 2 选择要安装sentry的主机 3 配置数据库 HDFS配置 开启启动访问控制列表 选中打勾 开启检查HDFS权限服务 开启sentry服务 hive配置 修改hive配置参数
  • 获取IronSource的广告源Pod和Maven版本

    接入IronSource库后 现在可以选择Maven或者Pod的形式导入相关广告源 Ironsource官网上有一个入口 可以方便的获取接入广告源的Maven和Pod Android https developers ironsrc com
  • Object.keys()、Object.values()、Object.entries()的用法

    一 Object keys obj 参数 要返回其枚举自身属性的对象 返回值 一个表示给定对象的所有可枚举属性的字符串数组 处理对象 返回可枚举的属性数组 let person name 张三 age 25 address 深圳 getNa
  • java参数校验常见注解介绍

    一 NotEmpty NotBlank NotNull区别介绍 NotEmpty 常用于集合 字符串等 不能为空 且长度必须大于0 NotBlank 用于字符串上 不能为空 且长度必须大于0 NotNull 字面意思 一般用于基本类型 不为
  • 聊聊编程是什么

    前言 前言不看没关系 不影响 半夜睡不着 想写点啥 浅聊下我理解的编程的 我认为编程就是解决问题 就像互联网是依附于实体业 是处理解决实际问题的 刚学编程的时候总是很恐慌的 天赋不够 我这么认为的原因 一是当时流行一种说法叫不是热爱编程的是
  • Mongodb数据库的安装部署及基本使用

    Mongodb数据库的安装部署及基本使用 一 Mongodb数据库介绍 1 Mongodb简介 2 Mongodb适用场景 3 MongoDB特性 二 检查本地系统环境 1 检查系统版本 2 检查yum仓库 三 Mongodb的安装 1 配
  • 【python开发】1. __init__.py与导包

    python开发 开始拿着github上的python代码狂啃时 发现很多知道干嘛又不知道为啥这样的代码 开始疯狂补漏 package 导包 用处1 导入包 比如这样的架构 package1 subPack1 init py module
  • 爬虫豆瓣top250

    爬虫豆瓣top250 前言 一 爬虫是什么 二 爬取豆瓣的原因 三 爬虫项目步骤 1 准备工具 2 学习python的相关知识 3 爬虫过程讲析 四 成果展示 五 代码展示 前言 随着网络的迅速发展 万维网成为大量信息的载体 如何有效地提取
  • 深度学习理论_卷积神经网络

    1 要点 激活函数一般用于卷积层和全连接层之后 激活函数是深度网络非线性的主要来源 常见的激活函数Sigmoid 双曲正切 ReLU 生物启发 克服了梯度消失问题 PReLU alpha可学习 ELU和maxout 其中PReLU和ELU都
  • MQClientException: CODE: 208  DESC: query message by key finished, but no message.

    2019 05 15 10 19 31 401 INFO closeChannel close the connection to remote address 127 0 0 1 10911 result true 2019 05 15
  • lua的for循环

    lua的三种for循环介绍 本文的lua代码编辑于luaforwindows 1 数值for循环 如图 举例如下 2 ipairs迭代器 举例如下 说明 ipairs按照索引值顺序 打印出了table中有索引值的数据 没有索引值的不管 3
  • 自定义mvc原理和框架实现

    目录 1 什么是MVC 2 自定义MVC工作原理图 3 自定义mvc的简单实现 1 中央控制器 2 Action接口定义 3 实现子控制器 4 完善中央控制器 1 请求分发功能 2 使用配置文件配置action 3 请求参数处理 4 完善A
  • vector中emplace_back和push_back详解,源码解读

    C 11之前 通常使用push back 向容器中加入一个右值元素 临时对象 的时候 首先会调用构造函数构造这个临时对象 然后需要调用拷贝构造函数将这个临时对象放入容器中 原来的临时变量释放 这样造成的问题是临时变量申请的资源就浪费 C 1
  • 关系型数据库与非关系型数据库Nosql区别汇总

    目录 关系型数据库与非关系型数据库详细比较 关系型数据库与非关系型数据库优缺点对比 关于Nosql 1 Nosql 2 Nosql特点 3 Nosql主要主流产品 4 Nosql数据库四大分类 关系型数据库与非关系型数据库详细比较 1 关系
  • MATLAB 在向量后面加一个元素

    1 向量后面加元素 gt gt x 1 2 3 4 5 gt gt y 6 gt gt x x y x 1 2 3 4 5 62 构建矩阵
  • OpenLayers的点击事件

    OpenLayers的点击事件是附加在整个ol Map对象上的 var selectSingleClick new ol interaction Select map addInteraction selectSingleClick sel
  • JavaWeb技术之多表操作

    目录 1 多表关系 2 多表操作之一对多 2 1 数据表 2 2 创建实体类 2 3 建立两表之间的属性关系 2 4 创建Dao层接口代码和实现类 操作数据库 2 5 测试类 3 多表操作之多对一 3 1 在上一步的基础上 完成多对一 3

随机推荐

  • GNU MCU Eclipse (STM32调试) win7配置

    eclipse官方有开源项目对STM32开发支持较好 由于Eclipse更新较快 插件配置较麻烦 建议使用开源项目 打包下载后直接使用 前提是已安装好JDK 安装好的界面如下 ST LINK配置好调试界面如下 测试工程结构如下 设备安装包如
  • C++程序习题-将字符串按逆序输出[1.15]

    输入一个字符串 把其中的字符按逆序输出 如输入LIGHT 输出为THGIL 要求用string方法 include
  • 网站顶部添加滚动文字

    如果我们在自己网站上添加一段滚动的文字会显得更高级一些 下面就看我如何实现的吧 实现效果 具体看本站 实现代码 精心整理 1 来回滚动
  • 利用 SOAR 加快事件响应并加强网络安全

    随着攻击面的扩大和攻击变得越来越复杂 与网络攻击者的斗争重担落在了安全运营中心 SOC 身上 SOC 可以通过利用安全编排 自动化和响应 SOAR 平台来加强组织的安全态势 这一系列兼容的以安全为中心的软件可加快事件调查和响应速度 SOAR
  • 股指期货日内平仓手续费高,锁仓可以解决吗

    对于平今加收的品种 以股指为例 如何解决日内手续费过高的问题 解决方案如下 逻辑讲解 现阶段股指手续费 张三交易IF合约 如果是日内开仓 日内平仓的话 根据交易所的交易规则 则张三开仓扣除25元手续费 日内平仓的还需扣除378元手续费 总计
  • [计算机组成原理] 以低字节地址为字地址

    以低字节地址为字地址 就是小端存储模式 数据低位 或者说低字节 存储在内存低地址 以高字节地址为字地址 就是大端存储模式 数据低位 或者说高字节 存储在内存高地址 现在看一个例题 这个题目有一个需要明确的地方 什么是第一 第二 第三字节 对
  • WPF 实现多语言

    1 编写Chinese xml English xml文件 2 在项目的App xml文件中
  • laravel —— 神奇的服务容器

    容器 字面上理解就是装东西的东西 常见的变量 对象属性等都可以算是容器 一个容器能够装什么 全部取决于你对该容器的定义 当然 有这样一种容器 它存放的不是文本 数值 而是对象 对象的描述 类 接口 或者是提供对象的回调 通过这种容器 我们得
  • qt相关的demo集合

    自己写过的qt c 相关程序的demo集合 许多学习自网络中 很感谢大家的分享 源码地址 Qt与学习通页面 记录与Qt相关的代码 Gitee com 源码目录 echart简单应用 opencv图像处理 QSetting简单使用 QtAv播
  • 运维思考:Java进程管理规范

    需求 无论是在spring boot 还是spring cloud 项目中 随着应用的不断增多 JVM参数的统一管理的重要性就会凸显出来 否则你可能会遇到几个问题 Java进程出现性能问题 无GC日志支撑提供重要信息 OOM异常频发 无法通
  • JDK下载 JVM调优工具jvisualvm下载

    一 JDK JDK官网地址 二 visualvm visualvm官网 JDK8以及之前自带有有visualvm插件 JDK9以及之后就不自带 1 下载安装 官网下载解压后 在解压目录 etc visualvm conf设置JDK所在路径
  • 收藏

    点上方计算机视觉联盟获取更多干货 仅作学术分享 不代表本公众号立场 侵权联系删除 转载于 作者丨叶润源 来源丨https www yuque com yerunyuan ar9831 tsm0id Kfi4w 编辑丨极市平台 985人工智能
  • 【满分】【华为OD机试真题2023 JS】字符串解密

    华为OD机试真题 2023年度机试题库全覆盖 刷题指南点这里 字符串解密 知识点数组字符串排序 时间限制 1s 空间限制 256MB 限定语言 不限 题目描述 给定两个字符串string1和string2 string1是一个被加扰的字符串
  • 龙龙送外卖PTA

    龙龙是 饱了呀 外卖软件的注册骑手 负责送帕特小区的外卖 帕特小区的构造非常特别 都是双向道路且没有构成环 你可以简单地认为小区的路构成了一棵树 根结点是外卖站 树上的结点就是要送餐的地址 每到中午 12 点 帕特小区就进入了点餐高峰 一开
  • 每日一题:给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

    每日一题 给定一个整数数组 nums 找到一个具有最大和的连续子数组 子数组最少包含一个元素 返回其最大和 2020年11月20日 力扣 简单 最大子序和 一 题目描述 给定一个整数数组 nums 找到一个具有最大和的连续子数组 子数组最少
  • 云数据中心备份容灾设计方案

    导读 云计算中心 涵盖系统多 类型复杂 关键性程度不一 因此对于恢复目标也有不同的要求 针对不同恢复目标的业务采取不同的灾备技术 同时考虑到数据中心重要性 需要建立同城灾备数据中心 并规划异地灾备中心 实现两地三中心 云数据中心备份容灾设计
  • 云服务器怎么设置数据库文件,服务器上数据库文件共享设置

    服务器上数据库文件共享设置 内容精选 换一换 本章节适用于MRS 3 x之前版本 Loader支持以下多种连接 每种连接的配置介绍可根据本章节内容了解 obs connectorgeneric jdbc connectorftp conne
  • 【2023】华为OD机试真题Java-题目0202-去除多余空格

    去除多余空格 题目描述 去除文本多余空格 但不去除配对单引号之间的多余空格 给出关键词的起始和结束下标 去除多余空格后刷新关键词的起始和结束下标 条件约束 不考虑关键词起始和结束位置为空格的场景 单词的的开始和结束下标保证涵盖一个完整的单词
  • 计算机无法访问外部网络怎么解决方案,局域网无法访问另一台计算机的解决方案...

    从网络邻居中打开工作组时显示 MSHOME 无法访问 您可能没有权限使用网络资源 请与这台服务器的管理员联系以查明您是否有访问权限 此工作组的服务器列表当前无法使用 可以PING通另一台 另一台可以访问这台 服务设置也差不多 本地安全策略来
  • 数据结构与算法C++实现(10)之哈希表

    一 概念 散列技术是在记录的存储位置和他的关键字之间建立一个确定的对应关系f 是的每个关键字key对应一个存储位置f key 查找时 根据这个对应的关系找到给定值key的映射f key 若查找集合中存在这个记录 则必定在f key 的位置上