关联式容器的特征:所用元素都会根据元素的键值自动被排序。

set

  • STL 中的关联式容器低层数据结构为红黑树,其功能都是调用低层数据结构中提供的相应接口。
  • set元的元素不会像map那样同时拥有键(key)和值(value)。
  • set元素的键就是值,值就是键,并不允许两个元素有相同的键。
  • multiset允许相同键值存在。
  • 因为set元素的键和值相等,所以不允许对set元素的值进行修改。(数据结构会根据key对元素进行排序,对value的更改会改变树中元素的排列顺序)。
  • set容器提供的迭代器为 const iterator;

    set类的声明:
template <class _Key, class _Compare, class _Alloc>
class set;

set类含三个模板参数,键类型_Key,键比较方法_Compare,分配器类型_Alloc;平时经常用到的是第一个模板参数:键类型_Key,如:

set<int> iset={1,2,3,4,5};

另外两个模板参数在特殊的应用场景上会发挥作用。_Compare模板参数可以指定容器中元素的比较方法,根据容器存放元素的大小,可修改内存分配策略_Alloc。这两个参数都可已通过设置set的构造函数参数来进行指定:

  explicit set(const _Compare& __comp,
const allocator_type& __a = allocator_type())
: _M_t(__comp, __a) {}

如果set未指定后两个模板参数,则会调用默认版本:

template <class _Key, class _Compare __STL_DEPENDENT_DEFAULT_TMPL(less<_Key>),
class _Alloc = __STL_DEFAULT_ALLOCATOR(_Key) >
class set;

map

  • map的每个元素都是一个pair<_key,_value>,同时拥有键值对。
  • map不允许两个元素的键相同。
  • map可以通过迭代器修改元素的值,但不能修改键(会改变元素排列)。map iterator 是一种介于const iterator 和mutable iterator 之间的迭代器。
template <class _Key, class _Tp, class _Compare, class _Alloc>
class map ;

map类有四个类模板参数,分别是:键类型_Key,值类型_Tp,键比较方法_Compare,分配器类型_Alloc;平时经常用到的是前两个模板参数:键类型_Key和值类型_Tp,如:

#include<iostream>
#include<map> using namespace std; int main(){
map<int,string> ismap={{1,"Hello"},{2,"World"}};
cout<<ismap[1]<<endl; //Hello
cout<<ismap[2]<<endl; //World return 0;
}

若不指定后两个参数,则会使用默认模板参数:

template <class _Key, class _Tp,
class _Compare __STL_DEPENDENT_DEFAULT_TMPL(less<_Key>),
class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) >
class map;

map的按照键映射值是通过[]运算符来进行的:

  _Tp& operator[](const key_type& __k) {
iterator __i = lower_bound(__k);
// __i->first is greater than or equivalent to __k.
// insert那句,根据键值和实值取出一个元素,由于实值未知,所以产生一个与实值
// 类型相同的暂时对象替代->value_type(__k,_Tp()),然后将这个元素插入到map里面
// 此时,__i指向插入之后的新位置的迭代器,然后在返回实值。
if (__i == end() || key_comp()(__k, (*__i).first))
__i = insert(__i, value_type(__k, _Tp()));
return (*__i).second;
}

该函数首先对键__k进行搜索,若没有找到,则在搜索结束位置插入新的节点。函数返回的是键所对应值的引用,因此,可以对其进行赋值。

multiset和multimap

multiset和multimap的用法和set,map的用法相同,不过它们允许重复的键。对应到源代码上就是,multi版本的插入操作调用红黑树的insert_equal接口,而普通版本则调用insert_unique接口。以multiset为例:

set版本

  pair<iterator,bool> insert(const value_type& __x) {
pair<typename _Rep_type::iterator, bool> __p = _M_t.insert_unique(__x);
return pair<iterator, bool>(__p.first, __p.second);
}

multiset版本

  iterator insert(const value_type& __x) {
return _M_t.insert_equal(__x);
}

小结

  • map和set是常用的关系型容器,两者内部都使用红黑树作为低层数据结构。类提供的接口都调用红黑树提供的相应接口。是对红黑树类的封装(适配)。
  • set和map中的元素都是自动排序的。
  • set的元素是键(等于值)。map的元素是键值对(key-value pair),可以提供键到值的映射功能。
  • set中的值(键)不能被修改,map中元素的值可以被修改,而键不能被修改。

STL关联式容器之set\map ----以STL源码为例的更多相关文章

  1. STL关联式容器之map和multimap

    一,map和multimap的概念 1.map和multimap的基本知识 map是标准的关联式容器,一个map是一个键值对序列,即(key,value)对.它提供基于key的快速检索能力. map中 ...

  2. STL关联式容器之set和multiset

    一,set和multiset的基础知识 1.set和multiset的基础 set是一个集合容器,其中所包含的元素是唯一的,集合中的元素按照一定的顺序排列,元素插入过程是按照排序规则插入的.所以不能指 ...

  3. STL序列式容器之list

    一,list容器基本概念 1.list容器基本知识 list容器的底部数据结构为双向链表,可以高效的进行插入和删除元素. list因为底层数据结构是双向链表,因此不支持下标操作和.at()函数的操作. ...

  4. STL——关联式容器

    一.关联式容器 标准的STL关联式容器分为set(集合)/map(映射表)两大类,以及这两大类的衍生体multiset(多键集合)和 multimap(多键映射表).这些容器的底层机制均以RB-tre ...

  5. 一篇文章带您读懂Map集合(源码分析)

    今天要分享的Java集合是Map,主要是针对它的常见实现类HashMap进行讲解(jdk1.8) 什么是Map核心方法源码剖析1.文档注释2.成员变量3.构造方法4.put()5.get() 什么是M ...

  6. C++ 序列式容器之vector

     什么是容器 容器,顾名思义,是用来容放东西的场所.C++容器容放某种数据结构,以利于对数据的搜寻或排序或其他特殊目的.众所周知,常用的数据结构不外乎:数组array,  链表list,  树tree ...

  7. Java显式锁学习总结之五:ReentrantReadWriteLock源码分析

    概述 我们在介绍AbstractQueuedSynchronizer的时候介绍过,AQS支持独占式同步状态获取/释放.共享式同步状态获取/释放两种模式,对应的典型应用分别是ReentrantLock和 ...

  8. Java显式锁学习总结之六:Condition源码分析

    概述 先来回顾一下java中的等待/通知机制 我们有时会遇到这样的场景:线程A执行到某个点的时候,因为某个条件condition不满足,需要线程A暂停:等到线程B修改了条件condition,使con ...

  9. Java集合之Map和Set源码分析

    以前就知道Set和Map是java中的两种集合,Set代表集合元素无序.不可重复的集合:Map是代表一种由多个key-value对组成的集合.然后两个集合分别有增删改查的方法.然后就迷迷糊糊地用着.突 ...

随机推荐

  1. PAT Basic 1037 在霍格沃茨找零钱 (20 分)

    如果你是哈利·波特迷,你会知道魔法世界有它自己的货币系统 —— 就如海格告诉哈利的:“十七个银西可(Sickle)兑一个加隆(Galleon),二十九个纳特(Knut)兑一个西可,很容易.”现在,给定 ...

  2. 网络流 最大流SAPkuangbin模板

    hdu 1532 求1~n的最大流 #include<stdio.h> #include<string.h> #include<algorithm> #includ ...

  3. aidl 详解

    aidl 是 android interface define language 的缩写,主要是作为进程间通讯的一个接口规范,这种通讯是一种普通的 client-server 的模式,对于 clien ...

  4. 接触oracle的第二天

    1.2 Sqlplus 这是一个轻量级的功能强大的客户端, 是 dba 必须掌握的工具. 我们可以配置 sqlplus 的一些行为,两个命令: show. 用来显示配置参数 set. 用来设置配置参数 ...

  5. 【NOIP2016提高A组8.12】通讯

    题目 "这一切都是命运石之门的选择." 试图研制时间机器的机关SERN截获了中二科学家伦太郎发往过去的一条短信,并由此得知了伦太郎制作出了电话微波炉(仮). 为了掌握时间机器的技术 ...

  6. 13 Spring Boot Shiro使用JS-CSS-IMG

    filterChainMap.put("/403", "anon");filterChainMap.put("/assets/**", &q ...

  7. PHP基础教程 常见PHP错误类型及屏蔽方法

    程序只要在运行,就免不了会出现错误,错误很常见,比如Error,Notice,Warning等等.这篇文章兄弟连PHP培训 小编来跟大家具体说一下PHP的错误类型和屏蔽方法.在 PHP 中,主要有以下 ...

  8. time,sys,os模块

      1.time模块 a:结构化时间:struct_time:通过time.localtime获取到一个时间对象,通过这个对象得到对象属性 ****localtime()如果没有参数,默认返回是一个时 ...

  9. 改变input的placeholder字体颜色

    改变input的placeholder字体颜色,注意哦,只是placeholder的字,用户输入的字不可以 input::-webkit-input-placeholder{ coloc:#000; ...

  10. Cmdow-一个win32窗口管理命令行工具

    最近有个需求,将同一个程序运行8个实例,并按照规则在两个窗口上分布,本以为用bat就可以实现,结果发现没那么容易,搜了很久找到了这个工具cmdow.exe,发现这个东西真不错. 符合了我们项目的需求: ...