当前位置: 首页 > news >正文

C++ map和unordered_map的区别

unordered_map 类模板和 map 类模板都是描述了这么一个对象:它是由 std::pair<const Key, value> 组成的可变长容器;

这个容器中每个元素存储两个对象,也就是 key - value 对。

1. unordered_map 

在头文件上,引入 <unordered_map> 来使用它。对于 unordered_map 而言,最大的特点在于内部实现上,使用到了「哈希表」(散列表、hash_table )来进行映射存储,它的模板类声明及其参数如下:

/*** 程序来自STL源码 bits/unordered_map.h*/
template<typename _Key,  // key 类型 typename _Tp,    // value 类型typename _Hash = hash <_Key>,     // 哈希函数typename _Pred = equal_to <_Key>, // 用于比较两者是否相同的函数typename _Alloc = allocator <std::pair<const _Key, _Tp>>> // 分配器,描述了容器在内存管理上的细节,不应该自己来处理,除非写自己的容器
class unordered_map {
};

在 unordered_map 内部,使用的 Hash Table 对数据进行组织,通过把键值 key 映射到 hash 表中的一个位置进行访问,根据 hash 函数的特点, unordered_map 对于元素查找的时间复杂度可以达到 O(1) ,但是,它的元素排列是无序的。具体例子如下: 

int main() {using namespace std;// 首先创建一个无序 map,它的 key 使用 int 类型,value 使用 string 类型unordered_map<int, string> unorderedMap;    // 三种插入新元素的方法,“茴”字有三种写法~unorderedMap.insert(make_pair(0, "Alice")); unorderedMap[1] = "Bob";unorderedMap.insert(unordered_map<int, string>::value_type(2, "Candy"));// 对内部元素挨个输出for (auto iter = unorderedMap.begin(); iter != unorderedMap.end(); iter++) {cout << iter->first << " - " << iter->second << endl;/** >: 输出如下,可以得知它们在 key 的排序上并没有顺序* 2 - Candy* 0 - Alice* 1 - Bob*/}
}

unordered_map 由于建立了哈希表,所以它在最开始建立的时候比较耗时间,但是它查询速度快呀~,一般情况下用 unordered_map 是没有问题的。 

2. map 

对于 map 而言,首先在头文件上,引用 <map> 进来,然后使用。它的类模板声明以及部分函数声明如下:

/*** 程序来自C++源码 bits/stl_map.h*/
template<typename _Key,  // key 类型typename _Tp,    // value 类型typename _Compare = std::less<_Key>, // 用于比较两个元素的比较函数typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > > // 分配器,同样的描述了容器在内存管理上的细节,不应该自己来处理,除非写自己的容器
class map {
private:/// 将一个红黑树转换成 [multi]map.typedef typename __gnu_cxx::__alloc_traits<_Alloc>::templaterebind<value_type>::other _Pair_alloc_type;typedef _Rb_tree<key_type, value_type, _Select1st<value_type>,key_compare, _Pair_alloc_type> _Rep_type;
};

在 map 的内部,使用了「红黑树」(red-black tree来组织数据,因此默认的就已经实现了数据的排序。从下面例子中可以看出,它默认实现了在 key 上排序实现递增: 

int main() {map<int, string> mapper;mapper.insert(make_pair(0, "Alice"));mapper[1] = "Bob";mapper.insert(map<int, string>::value_type(2, "Candy"));for (auto &iter : mapper) {cout << iter.first << " - " << iter.second << endl;/** >: 输出如下,很明显的,它们在 key 的排序上是递增排列的* 0 - Alice* 1 - Bob* 2 - Candy*/}
}

不过,在存储上 map 却比较占用空间,因为在红黑树中,每一个节点都要额外保存父节点和子节点的连接,因此使得每一个节点都占用较大空间来维护红黑树性质。 

3. 总结 

 两种数据结构特点如下表格~

unordered_mapmap
查找快,Average:O(1) ,Worst Case:O(n)恒定的 log(n)
插入和上面一样log(n) + 平衡二叉树所用时间
删除和上面一样log(n) + 平衡二叉树所用时间
是否排序不排序排序
实现方法哈希表红黑树
适用于查找操作频率高要求结果有序(按key排序)

相关文章:

C++ map和unordered_map的区别

unordered_map 类模板和 map 类模板都是描述了这么一个对象&#xff1a;它是由 std::pair<const Key, value> 组成的可变长容器&#xff1b; 这个容器中每个元素存储两个对象&#xff0c;也就是 key - value 对。 1. unordered_map 在头文件上&#xff0c;引入 <unor…...

BCSP-玄子JAVA开发之JAVA数据库编程CH-04_SQL高级(二)

BCSP-玄子JAVA开发之JAVA数据库编程CH-04_SQL高级&#xff08;二&#xff09; 4.1 IN 4.1.1 IN 子查询 如果子查询的结果为多个值&#xff0c;就会导致代码报错解决方案就是使用 IN 关键字&#xff0c;将 替换成 IN SELECT …… FROM 表名 WHERE 字段名 IN (子查询);4.1.…...

学习java——②面向对象的三大特征

目录 面向对象的三大基本特征 封装 封装demo 继承 继承demo 多态 面向对象的三大基本特征 我们说面向对象的开发范式&#xff0c;其实是对现实世界的理解和抽象的方法&#xff0c;那么&#xff0c;具体如何将现实世界抽象成代码呢&#xff1f;这就需要运用到面向对象的三大…...

初阶数据结构 - 【单链表】

目录 前言&#xff1a; 1.概念 链表定义 结点结构体定义 结点的创建 2.链表的头插法 动画演示 代码实现 3.链表的尾插 动画演示 代码实现 4.链表的头删 动画演示 代码实现 5.链表的尾删 动画演示 代码实现 6.链表从中间插入结点 动画演示 代码实现 7.从单…...

第五周作业、第一次作业(1.5个小时)、练习一

一、创建servlet的过程没有太多好说的&#xff0c;唯一需要注意的就是&#xff1a;旧版本的servlet确实需要手动配置web.xml文件&#xff0c;但是servlet2.5以后,servlet的配置直接在Java代码中进行注解配置。我用的版本就不再需要手动去配置web.xml文件了&#xff0c;所以我只…...

【正点原子FPGA连载】 第三十三章基于lwip的tftp server实验 摘自【正点原子】DFZU2EG_4EV MPSoC之嵌入式Vitis开发指南

第三十三章基于lwip的tftp server实验 文件传输是网络环境中的一项基本应用&#xff0c;其作用是将一台电子设备中的文件传输到另一台可能相距很远的电子设备中。TFTP作为TCP/IP协议族中的一个用来在客户机与服务器之间进行文件传输的协议&#xff0c;常用于无盘工作站、路由器…...

蓝桥冲刺31天之316

如果生活突然向你发难 躲不过那就迎面而战 所谓无坚不摧 是能享受最好的&#xff0c;也能承受最坏的 大不了逢山开路&#xff0c;遇水搭桥 若你决定灿烂&#xff0c;山无遮&#xff0c;海无拦 A&#xff1a;特殊日期 问题描述 对于一个日期&#xff0c;我们可以计算出年份的各个…...

说一个通俗易懂的PLC工程师岗位要求

你到了一家新的单位&#xff0c;人家接了一套新的设备&#xff0c;在了解设备工艺流程之后&#xff0c;你就能决定用什么电气元件&#xff0c;至少95%以上电气原件不论你用过没用过都有把握拍板使用&#xff0c;剩下5%&#xff0c;3%你可以先买来做实验&#xff0c;这次不能用&…...

今年还能学java么?

“Java很卷”、“大家不要再卷Java了”&#xff0c;经常听到同学这样抱怨。但同时&#xff0c;Java的高薪也在吸引越来越多的同学。不少同学开始疑惑&#xff1a;既然Java这么卷&#xff0c;还值得我入行吗&#xff1f; 首先先给你吃一颗定心丸&#xff1a;现在选择Java依然有…...

ajax学习1

不刷新页面的情况下&#xff0c;向服务端发送请求&#xff0c;异步的js和XMLajax不是新的编程语言&#xff0c;只是把现有标准组合到一起使用的新方式...

一题多解-八数码(万字长文)

16 张炜皓 (ζ͡顾念̶) LV 5 1 周前 在做这道题前&#xff0c;先来认识一下deque双端队列 C STL 中的双端队列 题目连接 使用前需要先引入 头文件。 #include; STL 中对 deque 的定义 // clang-format off template< class T, class Allocator std::allocator class d…...

九种跨域方式实现原理(完整版)

前言 前后端数据交互经常会碰到请求跨域&#xff0c;什么是跨域&#xff0c;以及有哪几种跨域方式&#xff0c;这是本文要探讨的内容。 一、什么是跨域&#xff1f; 1.什么是同源策略及其限制内容&#xff1f; 同源策略是一种约定&#xff0c;它是浏览器最核心也最基本的安…...

fighting

目录Mysqlgroup by和 distinct哪个性能好java觉得Optional类怎么样isEmpty和isBlank的用法区别使用大对象时需要注意什么内存溢出和内存泄漏的区别及详解SpringResource和Autowired的起源既生“Resource”&#xff0c;何生“Autowired”使用Autowired时为什么Idea会曝出黄色警告…...

网络安全日志监控管理

内部安全的重要性 无论大小&#xff0c;每个拥有IT基础设施的组织都容易发生内部安全攻击。您的损失等同于黑客的收益&#xff1a;访问机密数据、滥用检索到的信息、系统崩溃&#xff0c;以及其他等等。专注于网络外部的入侵是明智的&#xff0c;但同时&#xff0c;内部安全也…...

线程池的使用:如何写出高效的多线程程序?

目录1.线程池的使用2.编写高效的多线程程序Java提供了Executor框架来支持线程池的实现&#xff0c;通过Executor框架&#xff0c;可以快速地创建和管理线程池&#xff0c;从而更加方便地编写多线程程序。 1.线程池的使用 在使用线程池时&#xff0c;需要注意以下几点&#xff…...

React 架构流程概览

React 架构流程概览 文章目录React 架构流程概览启动React项目流程分析各部分解析调度器协调器渲染器总结启动React项目 启动项目&#xff0c;并打开 Performance 面板 流程分析 首先找到入口函数 整个 render 下面的调用栈就是首屏渲染要执行的流程。 render 过程大致分为…...

【Linux】进程管理之kill、killall、pkill

一、kill 命令 Linux 中的 kill 命令用来终止指定的进程的运行&#xff0c;是 Linux 下进程管理的常用命令。通常&#xff0c;终止一个前台进程可以使用 CtrlC 键&#xff0c;但是&#xff0c;对于一个后台进程就须用 kill 命令来终止&#xff0c;那就需要先使用 ps、pidof、ps…...

LSTM从入门到精通(形象的图解,详细的代码和注释,完美的数学推导过程)

先附上这篇文章的一个思维导图什么是RNN按照八股文来说&#xff1a;RNN实际上就是一个带有记忆的时间序列的预测模型RNN的细胞结构图如下&#xff1a;softmax激活函数只是我举的一个例子&#xff0c;实际上得到y<t>也可以通过其他的激活函数得到其中a<t-1>代表t-1时…...

19.特殊工具与技术

文章目录特殊工具与技术19.1控制内存分配19.1.1重载new和deleteoperator new接口和operator delete接口malloc函数与free函数19.1.2定位new表达式显式的析构函数调用19.2运行时类型识别(run-time type identification, RTTI)19.2.1dynamic_cast运算符指针类型的dynamic_cast引用…...

518. 零钱兑换 II ——【Leetcode每日一题】

518. 零钱兑换 II 给你一个整数数组 coins 表示不同面额的硬币&#xff0c;另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额&#xff0c;返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 3…...

FFmpeg 低延迟同屏方案

引言 在实时互动需求激增的当下&#xff0c;无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作&#xff0c;还是游戏直播的画面实时传输&#xff0c;低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架&#xff0c;凭借其灵活的编解码、数据…...

23-Oracle 23 ai 区块链表(Blockchain Table)

小伙伴有没有在金融强合规的领域中遇见&#xff0c;必须要保持数据不可变&#xff0c;管理员都无法修改和留痕的要求。比如医疗的电子病历中&#xff0c;影像检查检验结果不可篡改行的&#xff0c;药品追溯过程中数据只可插入无法删除的特性需求&#xff1b;登录日志、修改日志…...

质量体系的重要

质量体系是为确保产品、服务或过程质量满足规定要求&#xff0c;由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面&#xff1a; &#x1f3db;️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限&#xff0c;形成层级清晰的管理网络&#xf…...

(二)原型模式

原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)

笔记整理&#xff1a;刘治强&#xff0c;浙江大学硕士生&#xff0c;研究方向为知识图谱表示学习&#xff0c;大语言模型 论文链接&#xff1a;http://arxiv.org/abs/2407.16127 发表会议&#xff1a;ISWC 2024 1. 动机 传统的知识图谱补全&#xff08;KGC&#xff09;模型通过…...

(转)什么是DockerCompose?它有什么作用?

一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用&#xff0c;而无需手动一个个创建和运行容器。 Compose文件是一个文本文件&#xff0c;通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...

保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek

文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama&#xff08;有网络的电脑&#xff09;2.2.3 安装Ollama&#xff08;无网络的电脑&#xff09;2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要&#xff1a; 近期&#xff0c;在使用较新版本的OpenSSH客户端连接老旧SSH服务器时&#xff0c;会遇到 "no matching key exchange method found"​, "n…...

Web中间件--tomcat学习

Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机&#xff0c;它可以执行Java字节码。Java虚拟机是Java平台的一部分&#xff0c;Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...

NPOI操作EXCEL文件 ——CAD C# 二次开发

缺点:dll.版本容易加载错误。CAD加载插件时&#xff0c;没有加载所有类库。插件运行过程中用到某个类库&#xff0c;会从CAD的安装目录找&#xff0c;找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库&#xff0c;就用插件程序加载进…...