哈希表-set、map

当需要判断一个元素是否在集合中时,就使用哈希法

 散列表Hash table,也叫哈希表),是根据键(Key)而直接访问在内存存储位置的数据结构。

哈希表中关键码就是数组的索引下标,然后通过下标直接访问数组中的元素,复杂度O(1)

哈希表本质上是个数组,实现哈希表我们可以采用两种方法:

1、数组+链表

2、数组+二叉树

哈希函数

类似一个函数似的,给你一个值,经过某些加工得到另外一个值,就像这里的给你个人名,经过些许加工我们拿到首字母,那么这个函数或者是这个方法在哈希表中就叫做散列函数,其中规定的一些操作就叫做函数法则 

键值对,在jdk中就叫Entry

拉链法

刚刚小李和小王在索引1的位置发生了冲突,发生冲突的元素都被存储在链表中。 这样我们就可以通过索引找到小李和小王了

其实拉链法就是要选择适当的哈希表的大小,这样既不会因为数组空值而浪费大量内存,也不会因为链表太长而在查找上浪费太多时间。 

线性探测法

使用线性探测法,一定要保证tableSize大于dataSize。 我们需要依靠哈希表中的空位来解决碰撞问题。

例如冲突的位置,放了小李,那么就向下找一个空位放置小王的信息。

set

集合底层实现是否有序数值是否可以重复能否更改数值查询效率增删效率
std::set红黑树有序O(log n)O(log n)
std::multiset红黑树有序O(logn)O(logn)
std::unordered_set哈希表无序O(1)O(1)

std::unordered_set底层实现为哈希表,std::set 和std::multiset 的底层实现是红黑树,红黑树是一种平衡二叉搜索树,所以key值是有序的,但key不可以修改,改动key值会导致整棵树的错乱,所以只能删除和增加。

 

set会自动将元素排序,默认升序排列

	set<int> s;
	s.insert(1);
	s.insert(0);
	s.insert(3);
	s.insert(3);
	s.insert(4);
	s.insert(7);
	for (int c : s) {
		cout << c << "";
	}
	
	for (set<int>::iterator it = s.begin(); it != s.end();it++) {
		cout << *it << endl;
	}
	for (set<int>::iterator it = --s.end(); it != --s.begin(); it--) {
		cout << *it << ' ';
	}
    //反向迭代器
	for (set<int>::reverse_iterator it = s.rbegin(); it != s.rend();it++) {
		cout << *it << endl;
	}

map 

映射底层实现是否有序数值是否可以重复能否更改数值查询效率增删效率
std::map红黑树key有序key不可重复key不可修改O(logn)O(logn)
std::multimap红黑树key有序key可重复key不可修改O(log n)O(log n)
std::unordered_map哈希表key无序key不可重复key不可修改O(1)O(1)

std::unordered_map 底层实现为哈希表,std::map 和std::multimap 的底层实现是红黑树。同理,std::map 和std::multimap 的key也是有序的

 红黑树(Red Black Tree)也叫RB树

​​​​​​​

(1)为何map和set的插入删除效率比用其他序列容器高?

大部分人说,很简单,因为对于关联容器来说,不需要做内存拷贝和内存移动。说对了,确实如此。set容器内所有元素都是以节点的方式来存储,其节点结构和链表差不多,指向父节点和子节点。结构图可能如下:

  A
   / \
  B C
 / \ / \
  D E F G

因此插入的时候只需要稍做变换,把节点的指针指向新的节点就可以了。删除的时候类似,稍做变换后把指向删除节点的指针指向其他节点也OK了。这里的一切操作就是指针换来换去,和内存移动没有关系。

(2)为何每次insert之后,以前保存的iterator不会失效?

iterator这里就相当于指向节点的指针,内存没有变,指向内存的指针怎么会失效呢(当然被删除的那个元素本身已经失效了)。相对于vector来说,每一次删除和插入,指针都有可能失效,调用push_back在尾部插入也是如此。因为为了保证内部数据的连续存放,iterator指向的那块内存在删除和插入过程中可能已经被其他内存覆盖或者内存已经被释放了。即使时push_back的时候,容器内部空间可能不够,需要一块新的更大的内存,只有把以前的内存释放,申请新的更大的内存,复制已有的数据元素到新的内存,最后把需要插入的元素放到最后,那么以前的内存指针自然就不可用了。特别时在和find等算法在一起使用的时候,牢记这个原则:不要使用过期的iterator。

(3)当数据元素增多时,set的插入和搜索速度变化如何?

如果你知道log2的关系你应该就彻底了解这个答案。在set中查找是使用二分查找,也就是说,如果有16个元素,最多需要比较4次就能找到结果,有32个元素,最多比较5次。那么有10000个呢?最多比较的次数为log10000,最多为14次,如果是20000个元素呢?最多不过15次。看见了吧,当数据量增大一倍的时候,搜索次数只不过多了1次,多了1/14的搜索时间而已。你明白这个道理后,就可以安心往里面放入元素了。

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

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

相关文章

iOS合并代码后解决冲突

合并主干和分支代码后有冲突&#xff0c;xcode无法运行&#xff0c;如下图&#xff1a;文件显示不了&#xff0c;项目名也显示不了 解决冲突&#xff1a; 1.选中左边目录栏的项目名。鼠标右键--> Show in Finder 2.选中项目文件 xxxx.xcodeproj。鼠标右键--> 显示包内容…

人工智能基础部分22-几种卷积神经网络结构的介绍,并用pytorch框架搭建模型

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下人工智能基础部分22-几种卷积神经网络结构的介绍&#xff0c;本篇文章我将给大家详细介绍VGG16、VGG19、ResNet、SENet、MobileNet这几个卷积神经网络结构&#xff0c;以及pytorch搭建代码&#xff0c;利用通用数据…

JavaScript编程基础 – 对象

JavaScript编程基础 – 对象 JavaScript Programming Essentials – Object 本文简要介绍JavaScript面向对象编程&#xff0c;如何实现其中的对象以及实例演示&#xff0c;希望对大家学习JavaScript有所帮助。 1. 面向对象编程特点 面向对象编程(Object-Oriented Programmi…

阿里云服务器ECS产品知识及购买和使用常见问题及答案汇总

本文总结了阿里云用户在购买和使用阿里云服务器中的一些常见的问题&#xff0c;包括什么是云服务器ECS&#xff0c;特性与优势&#xff0c;应用场景&#xff0c;基本概念&#xff0c;使用限制等众多问题&#xff0c;让您全方位了解阿里云服务器&#xff0c;并根据自己的需求选择…

在ASP.NET Core 中使用 .NET Aspire 消息传递组件

前言 云原生应用程序通常需要可扩展的消息传递解决方案&#xff0c;以提供消息队列、主题和订阅等功能。.NET Aspire 组件简化了连接到各种消息传递提供程序&#xff08;例如 Azure 服务总线&#xff09;的过程。在本教程中&#xff0c;小编将为大家介绍如何创建一个 ASP.NET …

Lora学习资料汇总

目录 LoRa联盟 Semtech lora网关供应商: LoRaMAC API文档 论坛 开发板 主流技术对比分析 LoRa网络距离模拟测试方法 LoRa应用 LoRa联盟 LoRa联盟&#xff1a;LoRaWAN规范的制定组织 https://www.lora-alliance.org/ LoRa技术白皮书&#xff1a;https://www.lora-alli…

vue2指令的使用和自定义指令

前言 个人认为vue的指令,对比react来说,给开发者节省了很大的学习成本。比如在react中,你想渲染一个列表,需要用Array.map的方法return<div>,而在vue中,一个简单的v-for就解决了问题。 在学习成本和入手体验上,vue的作者确实后来者居上,能让人更快的使用vue开发。不过也…

【unity实战】如何更加规范的创建各种Rogue-Lite(肉鸽)风格的物品和BUFF效果(附项目源码)

文章目录 前言定义基类实现不同的BUFF效果一、回血BUFF1. 简单的回血效果实现2. BUFF层数控制回血量 二、攻击附带火焰伤害三、治疗领域1. 简单的治疗领域实现2. 添加技能冷却时间 通过拾取物品获取对应的BUFF参考源码完结 前言 当创建各种Rogue-Lite&#xff08;肉鸽&#xf…

接口传参数list的时候,items里面放个​​​​​​​list

item里面放个list 先定义一个 list&#xff0c;循环add加入参数

xorm源码学习

文章目录 XORM源码浅析及实践ORMORM vs. SQLXORM软件架构 ORM 引擎 Engine——DBM*core.DB Golang&#xff1a;database/sql 源码基本结构连接复用&#xff0c;提高性能。增加数据库连接池数量连接管理 database/sql主要内容&#xff1a;sql.DB创建数据库连接sql.Open()DB.conn…

状态设计模式是什么?什么是 State 状态设计模式?Python 状态设计模式示例代码

什么是 State 状态设计模式&#xff1f; 状态设计模式是一种行为型设计模式&#xff0c;它允许一个对象在其内部状态发生改变时改变其行为&#xff0c;使其看起来好像改变了其类。状态模式主要解决的问题是&#xff1a;当一个对象的行为取决于它的状态&#xff0c;并且在运行时…

2023年亚太地区数学建模大赛

中国新能源电动汽车的发展趋势 新能源汽车是指采用先进的技术原理、新技术和新结构&#xff0c;以非常规车用燃料&#xff08;非常规车用燃料是指汽油和柴油以外的燃料&#xff09;为动力源&#xff0c;集成先进的汽车动力控制和驱动技术的汽车。新能源汽车包括四大类型&#…

人工智能带来的各方面影响

近年来&#xff0c;人工智能&#xff08;AI&#xff09;技术在各个领域中的应用越来越广泛&#xff0c;已经开始对我们的生活方式、社会和经济结构产生深远的影响。 1.人工智能家庭化。人工智能技术使我们的生活变得更加便利和智能化。在家庭日常中&#xff0c;智能家居、智能…

WPF绘图使用介绍

文章目录 WPF绘图基本用法绘制直线在XAML中绘制直线在C#代码中绘制直线使用Path绘制直线注意 矩形绘制在XAML中绘制矩形在C#代码中绘制矩形设置矩形的位置使用圆角矩形 画刷1. SolidColorBrush2. LinearGradientBrush3. RadialGradientBrush4. ImageBrush5. DrawingBrush6. Vis…

FDG6306P PowerTrench® MOSFET P沟道 特点及其应用详解

关于PowerTrench MOSFET&#xff1f; 它是一种MOS场效应晶体管&#xff0c;可以提高系统效率和功率密度。该技术采用了屏蔽栅极技术&#xff0c;可以减少开关损耗和导通损耗&#xff0c;从而提高了系统效率。此外&#xff0c;PowerTrench MOSFET还具有低导通电阻和高开关速度的…

Python---函数的应用案例(多个)涉及函数、字符串翻转修改

案例&#xff1a;使用print方法打印一条横线 下面是最原始的方法&#xff1a; print(- * 40) 案例&#xff1a;对上个案例进行升级&#xff0c;可以根据输入的num数值&#xff0c;生成指定数量的横线 相关链接Python----range方法&#xff08;函数&#xff09;-CSDN博客 Pyt…

现代计算与光学的跨界机遇——

时至今日&#xff0c;互补氧化金属半导体&#xff08;CMOS&#xff09;技术的飞速发展促进了集成电路的空前成功。 晶体管的创新与时俱进 正如戈登-E-摩尔&#xff08;Gordon E. Moors&#xff09;在1965年预测的那样&#xff0c;每隔18-24个月&#xff0c;计算芯片上的晶体管数…

手把手教你通过CODESYS V3进行PLC编程(二)

教程背景 在上一期教程中&#xff0c;我们已经完成了控制器设备的连接和配置。接下来的教程将继续以宏集MC-Prime为例&#xff0c;假设控制器已经配置并连接到开发者的PC上&#xff0c;为您演示如何为控制器安装合适的CODESYS V3版本并创建第一个程序。 一、安装CODESYS &…

TikTok青年领袖:短视频如何塑造新一代

在数字时代的潮流中&#xff0c;短视频平台TikTok崭露头角&#xff0c;成为年轻一代最喜爱的社交媒体之一。这个平台不仅改变了用户的娱乐方式&#xff0c;更在其中催生了一批富有创造力和影响力的青年领袖。 本文将深入探讨TikTok如何通过短视频内容塑造新一代的青年领袖&…

Modbus转Profinet改变局面,PLC与电力仪表秒级响应

Modbus转Profinet改变了传统的局面&#xff0c;实现了PLC与电力仪表之间的秒级响应。在过去&#xff0c;由于Modbus通信协议的限制&#xff0c;PLC与电力仪表之间的数据传输速度受到了很大的限制&#xff0c;无法满足工业自动化领域对实时性的要求。然而&#xff0c;随着Modbus…