STL中的Set和Map

先来看一段网络上的文字描述:

上图是一段关于STL中Set集合的描述,同样的,也近似适合Map的描述。上述文字中,描述了最为重要的特征:

Set和Map,底层调用了红黑树的结构,并且实现的是一种自动平衡二叉搜索树。

  • Set

平衡二叉搜索树(Set)

如上图,STL中Set实现的本质是),insert(5),则只会执行第一次的insert操作。后续的插入,并不会执行,因为Set结构的树中无重复元素。

另一个点在于,Set中被插入的键不能被修改,也就是通过迭代器修改键值是不被允许的。因为键值一旦被修改,就意味着树的结构遭到了破坏,而这在最坏的情况意味着:整棵二叉树遭到了破坏,甚至需要重构整棵二叉树。即使在红黑树中,并没有这样的操作。因为红黑树的最为显著的特征为:局部调整。即对于Set而言,其iterator属于const-iterator。

另外一个需要被注意的点在于:

我们使用迭代器来访问容器是一件很平常的事情,上述代码是一段使用极其平常的代码,其作用是遍历Set中所有的元素。注意循环的终止条件是:!=,而不是:<。我们通常习惯了小于的小法:

即:

但这样的写法是错误的。

上述讲述了set的插入和遍历的过程,下面补充一点关于查找的知识点:

     set<int>::iterator ite;
     ite = set1.find();
     if(ite != set1.end())
     {
         cout<<"5 found"<<endl;
     }
     ite = set1.find();
     if(ite == set1.end())
     {
         cout<<"1 not found"<<endl;
     }
     cout<<endl;

可以,如果想查找某一个元素在set中是否存在,使用容器的方法find来查找key,方法find返回的是迭代器,如果找到(即存在这个键),则迭代器不等于set.end(),否则的话,没找到,返回的迭代器等于set.end()。

  • Map

下面来看Map,Map的结构形成机理和Set几乎是一模一样的,而Map的结构如下:

"挂件"平衡二叉搜索树(Map)

Map的结构如上图:可见,Set相比,Map只是多了一个"挂件",也就是常说的Map是由:键—值对构成的。键充当了索引,值则记录了一些其他内容。而对于Set而言,只有键。或许我们用下面这个表来描述更为合适:

键—值对

索引序号

名字

1

张三

2

李四

3

王五

左边的索引号就是键,右边的名字就是值,所以说Map实际上是一种极为普遍简单的概念。这种关系就像字典一样。

而关于Map的其他性质,和Set是极其类似的。比如:没有相同的元素,当然对于Map而言,没有相同的元素是只没有两个元素键相同。执行两个insert,仍然会只有一对键值对存在树中,且第二次执行insert不会修改第一次的值,如下图:

上述代码执行的结果:key=1的节点的value="master",而非是value="docter";可见,执行两次insert,并不会修改同一个key所对应的value.但这并不意味着,Map中的值不能修改。在下面我们将认识到这一点。

在上述代码中,我们使用了类似于数组的索引方式,试图对key=1的节点进行修改,最终将key=1节点的value值修改为了"dcoter"。下面,我们来看看,通过迭代器的索引方式能否修改value,

上述中,我们使用了迭代器的索引方式,结果节点key=1的value值也被修改为了"docter"。由此可见,调用insert方法并不能修改key所对应的value值。另外,我们仍然要给出在Map中,如何的访问键和值的做法:

可见,在Map中访问key的方式为:iterator->first;访问value的方式为iterator->second。

同样的,"的"王五"修改为"赵六";但我们不能将索引号3修改为4,(我们只能将3删除,再添加4,这是可以的)。当然是用迭代器访问时,其也只能用!=,而不是<

我们再来看看,关于Map一个很有意思的事情:

上图中,想表明两个点:

第一:有一行代码为:score["zhao liu"] = 93.5;可见,对于map而言,我们可以使用类似数组的索引方式,但是数组的索引只能是无符号整型索引,但是对于Map而言,则要广泛的多。可以是任意定义了的key的类型。

第二:我们看一下上述代码的运行结果:

前述内容表明:当索引key为整型的时候,Map的输出结果为按key升序输出。很明显,对于key为string类型而言,同样按照ASCII码的升序输出。

关于map的查找和set是类似的,并无什么高明的手段:

     map<string,double>::iterator ite_x;
     ite_x = score.find("zhang san");
     if(ite_x != score.end())
     {
         cout<<"zhang san found"<<endl;
     }
     cout<<endl;

如上图,仍然是通过迭代器的find方法进行查找。需要注意的是:我们在进行查找的时候,查找的一定是键,而不是值,这在set和map中是保持一致的。

而关于map,还有一点关于左值运用和右值运用的知识,如下图:

     score["zhao liu"] = 93.5;
     double zhao_score = score["zhao liu"];
     cout <<"zhao's score:"<<zhao_score<<endl;
     zhao_score = ;
     cout <<"zhao's score:"<<score["zhao liu"]<<endl;
     cout<<endl;

第一行代码是个左值引用,第二行代码为右值引用,即使zhao_score为引用,但是改变zhao_score的值,并不会改变score["zhao liu"]的值。

STL中的Set和Map——入门新手篇的更多相关文章

  1. C++ STL中哈希表Map 与 hash_map 介绍

    0 为什么需要hash_map 用过map吧?map提供一个很常用的功能,那就是提供key-value的存储和查找功能.例如,我要记录一个人名和相应的存储,而且随时增加,要快速查找和修改: 岳不群-华 ...

  2. stl中顺序性容器,关联容器两者粗略解释

    什么是容器 首先,我们必须理解一下什么是容器,在C++ 中容器被定义为:在数据存储上,有一种对象类型,它可以持有其它对象或指向其它对像的指针,这种对象类型就叫做容器.很简单,容器就是保存其它对象的对象 ...

  3. C++ STL中Map的按Key排序和按Value排序

    map是用来存放<key, value>键值对的数据结构,可以很方便快速的根据key查到相应的value.假如存储学生和其成绩(假定不存在重名,当然可以对重名加以区 分),我们用map来进 ...

  4. STL中map与hash_map的比较

    1. map : C++的STL中map是使用树来做查找算法; 时间复杂度:O(log2N) 2. hash_map : 使用hash表来排列配对,hash表是使用关键字来计算表位置; 时间复杂度:O ...

  5. STL中map与hash_map容器的选择收藏

    这篇文章来自我今天碰到的一个问题,一个朋友问我使用map和hash_map的效率问题,虽然我也了解一些,但是我不敢直接告诉朋友,因为我怕我说错了,通过我查询一些帖子,我这里做一个总结!内容分别来自al ...

  6. C++ STL中Map的相关排序操作:按Key排序和按Value排序 - 编程小径 - 博客频道 - CSDN.NET

    C++ STL中Map的相关排序操作:按Key排序和按Value排序 - 编程小径 - 博客频道 - CSDN.NET C++ STL中Map的相关排序操作:按Key排序和按Value排序 分类: C ...

  7. STL中map用法

    Map是 STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据处理能力,由于 这个特性,它完成有可能在我们处理一对一数据的 ...

  8. C++STL中map容器的说明和使用技巧(杂谈)

    1.map简介 map是一类关联式容器.它的特点是增加和删除节点对迭代器的影响很小,除了那个操作节点,对其他的节点都没有什么影响.对于迭代器来说,可以修改实值,而不能修改key. 2.map的功能 自 ...

  9. STL中关于map和set的四个问题?

    STL map和set的使用虽不复杂,但也有一些不易理解的地方,如: 为何map和set的插入删除效率比用其他序列容器高? 或许有得人能回答出来大概原因,但要彻底明白,还需要了解STL的底层数据结构. ...

随机推荐

  1. 通过 SCF Component 轻松构建 REST API,再也不用熬夜加班了

    本教程将分享如何通过 Serverless SCF Component .云函数 SCF 及 API 网关组件,快速构建一个 REST API 并实现 GET/PUT 操作. 当一个应用需要对第三方提 ...

  2. Python用WMI模块获取windowns系统信息

    安装vmi https://pypi.org/project/WMI/#history 脚本如下: #!/usr/bin/env python #coding:utf- import wmi impo ...

  3. javaIO编码详解

    原创 输出流 有哪些构造方法可以在参数上设置编码格式 PrintStream(File file, String csn) PrintStream(String fileName, String cs ...

  4. 如何在网页读取用户IP,操作系统版本等数据demo

    我们浏览网页的时候,会不经意间看到,有些地方(如个人的签名档)显示出了个人的IP,操作系统等数据.借助第三方API和请求报头useragent是很容易实现的. <html> <hea ...

  5. 2020-02-20Linux学习日记,第二天

    在内容开始前请教一下博客园的大佬.编辑器中没有看到格式刷,要怎么不连续的选中内容给予想要的格式,有看到的麻烦私信解答一下,谢谢! ----------------------------------- ...

  6. 动态主机配置协议-DHCP

    一.DHCP 概述 当局域网中有大量的PC时.如果我们逐个为每台PC去手动配置IP.那这就是一个吃力也未必讨好的办法 累死你 而DHCP 刚好可以解决这个问题.DHCP全称(动态主机配置协议).使用的 ...

  7. centos7 安装 iRedmail 后 给nginx添加虚拟主机

    iRedmail安装参考官方文档和 https://ywnz.com/linuxyffq/4563.html 准备工作 更新操作系统 yum update -y 安装必要组件 yum install ...

  8. 线索二叉树C++实现

    #include<iostream> #include<stdlib.h> #define maxsize 100 using namespace std; typedef s ...

  9. 数据算法 --hadoop/spark数据处理技巧 --(5.移动平均 6. 数据挖掘之购物篮分析MBA)

    五.移动平均 多个连续周期的时间序列数据平均值(按相同时间间隔得到的观察值,如每小时一次或每天一次)称为移动平均.之所以称之为移动,是因为随着新的时间序列数据的到来,要不断重新计算这个平均值,由于会删 ...

  10. spark 性能优化 数据倾斜 故障排除

    版本:V2.0 第一章       Spark 性能调优 1.1      常规性能调优 1.1.1   常规性能调优一:最优资源配置 Spark性能调优的第一步,就是为任务分配更多的资源,在一定范围 ...