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. springcloud Eureka设置服务下线上线事件通知

    最近由于微服务会莫名其妙挂掉,导致一些服务宕机: 固所以寻找解决办法,莫名宕机暂时还未查明原因,先人肉解决办法 Eureka的server端会发出5个事件通知,分别是: EurekaInstanceC ...

  2. 聊聊SpringBoot | 第一章:快速搭建SpringBoot第一个应用

    快速搭建SpringBoot第一个应用 1.简介 本章仅介绍如何快速搭建第一个SpringBoot应用,细节内容下一章再做讲解,如果有需要,各位可以直接到Spring官网去了解. 从 Spring B ...

  3. Web 开发工具类(1): CookieUtils

    CookieUtils 整合了常用的一些对Cookie的相关操作: package com.evan.common.utils; import java.io.UnsupportedEncodingE ...

  4. 曹工说Spring Boot源码(13)-- AspectJ的运行时织入(Load-Time-Weaving),基本内容是讲清楚了(附源码)

    写在前面的话 相关背景及资源: 曹工说Spring Boot源码(1)-- Bean Definition到底是什么,附spring思维导图分享 曹工说Spring Boot源码(2)-- Bean ...

  5. Linux学习笔记-centos查看版本号和内核信息

    1.查看centos系统版本号: 打开终端窗口: cat /etc/redhat-release 2.查看Linux内核版本信息: uname -a 或者 在图形化桌面右上角点开设置,在设置窗口选择详 ...

  6. python 不可变字典 inmutabledict的实现

    python inmutabledict的实现 关于在python中如何实现不可变字典的方法.早在pep416中,就建议python官方实现inmutabledict,但是官方否认了.理由主要是 根据 ...

  7. FFMPEG学习----分离视频里的H.264与YUV数据

    #include <stdio.h> extern "C" { #include "libavcodec/avcodec.h" #include & ...

  8. C++输出中文字符

    注:本文转载自互联网,感谢作者整理!   1. cout 场景1: 在源文件中定义 const char* str = "中文" 在 VC++ 编译器上,由于Windows环境用 ...

  9. JAVA&&JAVA WEB开发包U盘封装版

    难以忍受机房的开发环境,就简单实现了将所有的开发文件封装进了U盘. 基于wmic的强大功能,实现了机房变态环境下的设置环境变量OS不用重新启动OS! install.bat @echo off mod ...

  10. web开发发展历程

    cs架构:(软件主要运行在桌面上,数据库软件运行在服务器端) 缺点:如果web应用修改或升级,需要每个客户端逐个升级桌面App,因此Browser/server模式开始流行. bs架构:应用程序的逻辑 ...