数据结构-查找-哈希表

一、哈希表的映射方法

1、直接定址法(值的分布范围集中)

比如统计字符串中字符出现的次数,字符范围集中。

2、除留余数法(值的分布范围分散)

hashi = key % n

但是这种方法会导致,哈希冲突:不同的值映射到相同的位置

不同关键字通过相同哈希哈数计算出相同的哈希地址,该种现象称为哈希冲突
或哈希碰撞

解决哈希冲突的方案

闭散列的---开放定址法:当前位置被占用了,按规则找下一个位置(占用别人的位置)

1、线性探测

2、二次探测

.

二、查找的时候可以找的到,但是这个值在空的后面

查找逻辑:遇到空就停止查找。

可以使用状态来标记

1、EXIST

2、EMPTY

3、DELETE

查找的时候,遇到状态EMPTY才能停止。

三、哈希表什么时候扩容

散列表的载荷因子定义为 :填入表中的元素个数 /散列表的长度

负载因子越大,冲突概率越大,空间利用率越高

负载因子越小,冲突概率越小,空间利用率越低。空间浪费越多。

哈希表不能满了扩容,控制负载因子到一定值就扩容。负载因子可以限制在0.7~0.8之间。

四、扩容以后我们的映射关系就变了,需要重新映射。

解决方案:

1、 重新开一个vector,把旧的的值直接插入到新的vector里面中去。遍历旧表重新映射到新表。

2、我们可以重新搞一个hash表,把空间提前开好,遍历旧表插入到新表里。然后旧表和新表进行交换。

bool Insert(const pair<K, V>& kv)
	{
		// 扩容
		//if ((double)_n / (double)_table.size() >= 0.7)
		if (_n*10 / _table.size() >= 7)
		{
			size_t newSize = _table.size() * 2;
			// 遍历旧表,重新映射到新表
			HashTable<K, V, HashFunc> newHT;
			newHT._table.resize(newSize);

			// 遍历旧表的数据插入到新表即可
			for (size_t i = 0; i < _table.size(); i++)
			{
				if (_table[i]._state == EXIST)
				{
					newHT.Insert(_table[i]._kv);
				}
			}

			_table.swap(newHT._table);
		}

		// 线性探测
		HashFunc hf;
		size_t hashi = hf(kv.first) % _table.size();
		while (_table[hashi]._state == EXIST)
		{
			++hashi;
			hashi %= _table.size();
		}

		_table[hashi]._kv = kv;
		_table[hashi]._state = EXIST;
		++_n;

		return true;
	}

二次探测

hashi  = key%n

hashi = key%i^2

开放定址法的缺点:冲突会互相影响。

哈希桶:

第二种方法为哈希桶

插入:

        bool Insert(const T& data)
		{

			// 负载因子到1就扩容
			if (_n == _table.size())
			{
				// 16:03继续
				size_t newSize = _table.size()*2;
				vector<Node*> newTable;
				newTable.resize(newSize, nullptr);

				// 遍历旧表,顺手牵羊,把节点牵下来挂到新表
				for (size_t i = 0; i < _table.size(); i++)
				{
					Node* cur = _table[i];
					while (cur)
					{
						Node* next = cur->_next;

						// 头插到新表
						size_t hashi = cur->_data % newSize;
						cur->_next = newTable[hashi];
						newTable[hashi] = cur;

						cur = next;
					}

					_table[i] = nullptr;
				}

				_table.swap(newTable);
			}

			size_t hashi = data % _table.size();
			// 头插
			Node* newnode = new Node(data);
			newnode->_next = _table[hashi];
			_table[hashi] = newnode;
			++_n;
			return true;
		}

删除:

        bool Erase(const K& key)
		{
			
			size_t hashi = key % _table.size();
			Node* prev = nullptr;
			Node* cur = _table[hashi];
			while (cur)
			{
				if (kot(cur->_data) == key)
				{
					if (prev == nullptr)
					{
						_table[hashi] = cur->_next;
					}
					else
					{
						prev->_next = cur->_next;
					}

					--_n;
					delete cur;	
					return true;
				}

				prev = cur;
				cur = cur->_next;
			}

			return false;
		}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Python探索之旅】初识Python

目录 发展史&#xff1a; 环境安装&#xff1a; 入门案例&#xff1a; 变量类型 标准数据类型 数字类型&#xff1a; 字符串&#xff1a; 全篇总结&#xff1a; 前言&#xff1a; Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。 Python 的设…

CSS 之 圆形波浪进度条效果

一、简介 ​ 本篇博客讲述了如何实现一个圆形波浪进度条的样式效果&#xff0c;具体效果参考下方GIF图。该样式的加载进度条可以用在页面跳转或数据处理等情况下的加载动画&#xff0c;比起普通的横条进度条来说&#xff0c;样式效果更生动美观。 实现思路&#xff1a; ​ 这…

Wikimedia To Opensearch

概览 Wikimedia ⇒ Kafka ⇒ OpensearchJava Library&#xff1a;OKhttp3和OkHttp EventSource&#xff1b;生产者&#xff1a;Wikimedia&#xff1a;WikimediaChangeHandler和WikimediaChangeProducer&#xff1b;消费者&#xff1a;Opensearch&#xff1a;OpenSearchConsume…

代码随想录-算法训练营day38【动态规划01:理论基础、斐波那契数、爬楼梯、使用最小花费爬楼梯】

代码随想录-035期-算法训练营【博客笔记汇总表】-CSDN博客 第九章 动态规划part01● 理论基础 ● 509. 斐波那契数 ● 70. 爬楼梯 ● 746. 使用最小花费爬楼梯 详细布置 今天正式开始动态规划&#xff01;理论基础 无论大家之前对动态规划学到什么程度&#xff0c;一定要先看…

【Linux】了解信号产生的五种方式

文章目录 正文前的知识准备kill 命令查看信号man手册查看信号信号的处理方法 认识信号产生的5种方式1. 工具2. 键盘3. 系统调用kill 向任意进程发送任意信号raise 给调用方发送任意信号abort 给调用方发送SIGABRT信号 4. 软件条件5. 异常 正文前的知识准备 kill 命令查看信号 …

项目8-头像的上传

js实现头像上传并且预览图片功能以及提交 - 掘金 (juejin.cn) 我们简单建立一个表 1.前端知识储备 1.1 addClass的使用 1.基本语法 addClass() 方法向被选元素添加一个或多个类。 该方法不会移除已存在的 class 属性&#xff0c;仅仅添加一个或多个 class 属性。 提示&…

CentOS使用Docker搭建Nacos结合内网穿透实现无公网IP远程登录本地管理平台

文章目录 1. Docker 运行Nacos2. 本地访问Nacos3. Linux安装Cpolar4. 配置Nacos UI界面公网地址5. 远程访问 Nacos UI界面6. 固定Nacos UI界面公网地址7. 固定地址访问Nacos Nacos是阿里开放的一款中间件,也是一款服务注册中心&#xff0c;它主要提供三种功能&#xff1a;持久化…

LeetCode题练习与总结:不同的二叉搜索树Ⅱ--95

一、题目描述 给你一个整数 n &#xff0c;请你生成并返回所有由 n 个节点组成且节点值从 1 到 n 互不相同的不同 二叉搜索树 。可以按 任意顺序 返回答案。 示例 1&#xff1a; 输入&#xff1a;n 3 输出&#xff1a;[[1,null,2,null,3],[1,null,3,2],[2,1,3],[3,1,null,nul…

CNN/TCN/LSTM/BiGRU-Attention到底哪个模型效果最好?注意力机制全家桶来啦!

​ 声明&#xff1a;文章是从本人公众号中复制而来&#xff0c;因此&#xff0c;想最新最快了解各类智能优化算法及其改进的朋友&#xff0c;可关注我的公众号&#xff1a;强盛机器学习&#xff0c;不定期会有很多免费代码分享~ 目录 数据介绍 效果展示 原理简介 代…

Python---NumPy万字总结【此篇文章内容难度较大,线性代数模块】(3)

NumPy的应用&#xff08;3&#xff09; 向量 向量&#xff08;vector&#xff09;也叫矢量&#xff0c;是一个同时具有大小和方向&#xff0c;且满足平行四边形法则的几何对象。与向量相对的概念叫标量或数量&#xff0c;标量只有大小&#xff0c;绝大多数情况下没有方向。我们…

Ubuntu 超级终端Terminator常用使用技巧

Ubuntu 超级终端Terminator常用使用技巧 Terminator 是一款功能强大的终端模拟器&#xff0c;它特别适合于需要同时管理多个终端会话的用户。以下是如何在 Ubuntu 上使用 Terminator 的详细指南&#xff1a; 安装 Terminator 如果你的系统尚未安装 Terminator&#xff0c;你…

Prompt Engineering ,Fine-tuning , RAG ?

Prompt Engineering ,Fine-tuning , RAG 总结&#xff1a;1 prompt engineering2 RAG (Retrieval Augmented Generation)**RAG特点****RAG优势****RAG劣势** 3 微调&#xff08;Fine-tuning&#xff09;**微调特点****微调优势****微调劣势** 4 三者共性和区别5 RAG和微调的适应…

港中深「户外自重构蜗牛机器人集群」登Nature子刊!

在科幻电影《超能陆战队》中&#xff0c;我们见证了一种由成千上万个微小磁性单元组成的机器人通过磁力相互连接&#xff0c;形成各种复杂的三维结构。香港中文大学&#xff08;深圳&#xff09;林天麟教授团队致力于将这一科幻转化为现实&#xff0c;近年来开发了一系列自由形…

C++基础与深度解析 | 数组 | vector | string

文章目录 一、数组1.一维数组2.多维数组 二、vector三、string 一、数组 1.一维数组 在C中&#xff0c;数组用于存储具有相同类型和特定大小的元素集合。数组在内存中是连续存储的&#xff0c;并且支持通过索引快速访问元素。 数组的声明&#xff1a; 数组的声明指定了元素的…

【基础技能】Windows常用快捷键

最近做知识管理&#xff0c;梳理了下个人技能&#xff0c;存在好多基础技能都是一知半解&#xff0c;用的时候都是现搜现查&#xff0c;没有形成一个完整的知识体系&#xff0c;导致一些基础不牢靠&#xff0c;需要再次筑基&#xff01; 于是就翻阅了微软的官网&#xff0c;撸…

5.13网络编程

只要在一个电脑中的两个进程之间可以通过网络进行通信那么拥有公网ip的两个计算机的通信是一样的。但是一个局域网中的两台电脑上的虚拟机是不能进行通信的&#xff0c;因为这两个虚拟机在电脑中又有各自的局域网所以通信很难实现。 socket套接字是一种用于网络间进行通信的方…

Linux进程间几种通信机制

一. 简介 经过前一篇文章的学习&#xff0c; 我们知道Linux下有两种标准&#xff1a;system V标准和 Posix标准。 System V 和 POSIX 标准是操作系统提供的接口标准&#xff0c;它们规定了操作系统应该如何实现一些基本功能&#xff0c;比如线程、进程间通信、文件处理等。 …

【APM】在Kubernetes中搭建OpenTelemetry+Loki+Tempo+Grafana链路追踪(一)

文章目录 1、最终效果2、前提准备2、环境信息3、服务集成&#xff08;Opentelemetry ->Tempo&#xff09;3.1 上报链路数据3.1.1 下载opentelemetry-agent3.1.2 启动配置业务app3.1.3 配置opentelemetry输入输出3.1.4 配置grafana datasource3.1.4.1 配置tempo3.1.4.2 配置l…

基于RK3568的鸿蒙通行一体机方案项目

鸿蒙通行一体机方案以鸿蒙版AIoT-3568X人工智能主板为核心平台&#xff0c;搭载OpenHarmony操作系统&#xff0c;使用自研算法和国产芯片&#xff0c;可管可控&#xff0c;并提供身份识别以及其他外设配件生态链支持。 01 项目概述 项目使用场景 鸿蒙版通行一体机方案凭借自主…

【云计算小知识】云管理的作用是什么?

云计算已经成为推动企业数字化转型&#xff0c;提升运营效率的重要力量。而在这个过程中&#xff0c;云管理作为确保云计算环境稳定、高效运行的关键环节&#xff0c;其作用愈发凸显。今天我们小编就给大家详细介绍一下云管理的作用是什么&#xff1f; 云管理的作用是什么&…