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. Spring 框架初学

    一 .   spring IOC, DI: 将原来有程序员建立类的对象工作交由spring来操作: 从外部来看: 将各个类以bean 的方式配在spring容器的配置文件中(application.x ...

  2. SpringCloud与微服务Ⅲ --- SpringCloud入门概述

    一. 什么是SpringCloud SpringCloud基于SpringBoot提供了一套微服务解决方案,包括服务注册与发现,配置中心,全链路监控,服务网关,负载均衡,熔断器等组件,除了基于NetF ...

  3. 深入了解 Java 中的异常处理 + 面试题

    # 深入了解 Java 中的异常处理 + 面试题 在程序开发中,异常处理也是我们经常使用到的模块,只是平常很少去深究异常模块的一些知识点.比如,try-catch 处理要遵循的原则是什么,finall ...

  4. Unicode标准以及其常见的编码方案

    目录 基本概念 码位 码位的类型 编码方案 UTF-32 UTF-16 UTF-8 参考资料 Unicode标准为每一个字符提供一个唯一的数字,而不用区分平台.语言等因素. The Unicode S ...

  5. Shell case语法结构解析

    case ... esac 与其他语言中的 switch ... case 语句类似,是一种多分枝选择结构,每个 case 分支用右圆括号开始,用两个分号 ;; 表示 break,即执行结束,跳出整个 ...

  6. springboot整合druid和配置资源监控

    1.添加依赖,在maven repository中搜索 <dependency> <groupId>com.alibaba</groupId> <artifa ...

  7. Actix-web Rust连接Postgres数据库

    Actix-web Rust连接Postgres数据库 ​ Rust1.39支持了异步async,await,Actix-web在2.0.0-alpha支持了原生异步写法,所以本文中使用的Actix- ...

  8. sql中常量和变量的引用

    String name =jtf.getText().trim(); String sql="select * from stu where stuname='  "+name+& ...

  9. 概念验证:在Kubernetes中部署ABAP

    对于将SAP ABAP应用服务器组件容器化和在Kubernetes中部署它们,我们在SPA LinuxLab中做了概念验证(PoC),本文将介绍一些我们的发现和经验.本文会也会指出这项工作的一些潜在的 ...

  10. oracle查询表空间的空间占用情况

    ,) percent_used from (select tablespace_name,sum(bytes) bytes from dba_data_files group by tablespac ...