STL之关联容器---set, mutilset, map, mutilmap

时间:2021-10-06 09:26:31

STL的容器分为序列容器和关联容器。它们所表达的数据结构各有不同:

序列容器:vector(变长数组), list(链表), queue(队列), heap(堆算法)等

关联容器:set/mutilset,map/mutilmap,(都表达二叉树,且都由红黑树实现)

关联容器是指容器的元素为键值对(key-value),但这四种关联容器的键值对之间略有差异

一、set/mutilset

set是集合之意,其键值对的键和值相同,那么set更像普通的二叉树即结点是键值和实值。

set的键值不允许相同,所以set的value值也没有相同的。而这也是mutilset和set唯一的不同,mutilset可以有相同的键值。

set是基于红黑树的所以其中的元素会自动排序。

set常用操作:

定义set: set<int> a;

插入元素: a.insert(1);

删除元素: a.erase(1);

删除所有元素: a.clear():

判断容器是否为空: a.empty();

返回容器当前元素个数: a.size();

判断元素是否属于集合: if(a.find(1)!=a.end())则属于

集合的并,交,差:

set_union(a.begin(), a.end(), b.begin, b.end(), insert_iterator<set<int> >(c,c.begin()));

set_intersection(a.begin(),a.end(),b.begin(),b.end(),insert_iterator<set<int> >(c,c.begin()));

set_difference(a.begin(),a.end(),b.begin(),b.end(),insert_iterator<set<int> >(c,c.begin()));

以下是收集的关于set的问题:

(1)为何map和set的插入删除效率比用其他序列容器高?

因为对于关联容器来说,不需要做内存拷贝和内存移动。set容器内所有元素都是以节点的方式来存储,其节点结构和链表差不多,指向父节点和子节点。(用节点表示二叉树结构)

因此插入的时候只需要稍做变换,把节点的指针指向新的节点就可以了。删除的时候类似,稍做变换后把指向删除节点的指针指向其他节点也OK了。这里的一切操作就是指针换来换去,和内存移动没有关系。

(2)对set进行增删操作后,迭代器iterator如何变化?

set的迭代器本质上是const_iterator,这是因为RB-tree的结构依赖于数据的组织,如果允许通过iterator改变set元素值,会严重破坏RB-tree结构。

iterator这里就相当于指向节点的指针,内存没有变,指针就没有失效,只是指向的内容变化了。进行增删操作后,只影响本身的迭代器,对其它迭代器无影响。

示例代码:

 void test_set()
{
set<int> a;
for (int i=;i<;i++)
{
a.insert(i);
}
a.insert();
cout<<"set中第一个元素:"<<*a.begin()<<endl;
cout<<"set中元素个数:"<<a.size()<<endl;
int arr[]={,,};
a.insert(arr,arr+);
set<int>::iterator iter;
for (iter=a.begin();iter!=a.end();iter++)
{
cout<<*iter<<" ";
}
cout<<endl;
a.erase();
set<int>::iterator itl=a.begin();
itl++;
itl++;
a.erase(a.begin(),itl);
for (iter=a.begin();iter!=a.end();iter++)
{
cout<<*iter<<" ";
}
return;
}

结果:

STL之关联容器---set, mutilset, map, mutilmap

说明几点:元素1是第二次插入的,却在set第一个位置上,验证了set自动排序(升序);

在用数组插入时,我的区间是(arr,arr2)即(9,10,11),但是结果中没有11,说明insert()内区间也是左闭右开,即[arr,arr+2);这和下面的erase一样。

二、map/mutilmap

map是映射之意,即用键值(key)映射实值数据(value)。

对比set,map的关联特效更加明显,但类似set,map也不允许有相同的键值,要想有相同键值可用mutilmap。

可能你会疑问set只有一个相同的值,为何也算关联?这是因为set和map都是相同的数据结构,

它们都由pair这种结构生成,并根据pair第一个元素值进行排序。

map的常用操作:

定义map: map<int,string> b;

插入数据:b.insert(map<int, string>::value_type(1,"aaa"));

或数组插入:b[1]="aaa";

删除数据:b.erase(1);  或b.erase(b.begin(), iter);//注意删除区间是左闭右开

删除所有数据:b.clear();

数据遍历方式:迭代器遍历:

map<int, string>::iterator iter;

for(iter=b.begin();iter!=b.end();iter++)

{ cout<<iter->first<<" "<<iter->second<<endl;  }

数组遍历:

int bsize=b.size();

for(int i=1;i<=bsize;i++)

{ cout<<b[i]<<endl; }

示例代码:

 void test_map()
{
map<int, string> week;
week.insert(map<int,string>::value_type(,"monday"));
week.insert(map<int,string>::value_type(,"tuesday"));
week[]="wednesday";
week[]="thursday";
week[]="friday";
week[]="saturday";
week[]="sunday";
map<int, string>::iterator iter;
for (iter=week.begin();iter!=week.end();iter++)
{
cout<<iter->first<<":"<<iter->second<<" ";
}
cout<<endl;
///下面演示两种插入方式插入相同键值的不同结果
week.insert(map<int, string>::value_type(,"errorday1"));
cout<<"insert之后:"<<week[]<<endl;
week[]="errorday2";
cout<<"数组插入后:"<<week[]<<endl; week.erase();
map<int, string>::iterator itr=week.begin();
itr++;
itr++;
week.erase(week.begin(), itr);
for (iter=week.begin();iter!=week.end();iter++)
{
cout<<iter->first<<":"<<iter->second<<" ";
} return;
}

结果:

STL之关联容器---set, mutilset, map, mutilmap

说明几点:插入对比可看出insert插入相同键值的数据不会覆盖,而数组方式插入数据会覆盖相同键值的数据。

掌握这些基本知识后,可以试着用set和map去解决下实际问题。推荐看看这个写的。以后我也会陆续添加容器的应用实例。

STL之关联容器---set, mutilset, map, mutilmap的更多相关文章

  1. STL之关联容器的映射底层

    STL的关联容器有set, map, multiset, multimap.用于实现它们的底层容器有划入标准的rb_tree和待增加标准的hashtable. 底层容器rb_tree为上层容器提供了一 ...

  2. &num;&num;&num;STL学习--关联容器

    点击查看Evernote原文. #@author: gr #@date: 2014-08-23 #@email: forgerui@gmail.com STL中的关联容器. ###stl学习 |--迭 ...

  3. STL之关联容器

    关联容器包含map.set.multimap.multiset. 关联容器的特点是明显的,相对于顺序容器,有如下特点: 1.其内部是采用非线性的二叉树结构,具体的说是红黑树的结构原理实现的. 2.se ...

  4. c&plus;&plus;的关联容器入门(map and set)

    目录 std::map std::set C++的关联容器主要是两大类map和set 我们知道谈到C++容器时,我们会说到 顺序容器(Sequence containers),关联容器(Associa ...

  5. STL标准库-容器-set与map

    STL标准库-容器-set与multiset C++的set https://www.cnblogs.com/LearningTheLoad/p/7456024.html STL标准库-容器-map和 ...

  6. 【STL】关联容器 — hash&lowbar;set

    容器hash_set是以hash table为底层机制的,差点儿所有的操作都是转调用hash table提供的接口.因为插入无法存储同样的键值,所以hash_set的插入操作所有都使用hash tab ...

  7. 【STL】关联容器 — hashtable

    C++ 11哈希表已被列入标准列.hashtable这是hash_set.hash_map.hash_multiset.hash_multimap的底层机制.即这四种容器中都包括一个hashtable ...

  8. STL - 常用关联容器代码 - set &amp&semi; multiset

    代码如下: /* 5. set & multiset */ set<string> cities{ "Braunschweig", "Hanover& ...

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

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

随机推荐

  1. sql server 远程连接不上解决思路

    1.数据库是否允许远程连接: 1.1.0登陆SQL Server 2008(windows身份认证),登陆后右击,选择“属性”.左侧选择“安全性”,选中右侧的“SQL Server 和 Windows ...

  2. ToDoList:一款非常优秀的任务管理软件 —— 工具类

    ToDoList是一款非常优秀的任务管理软件,用户可以方便地组织和安排计划.这是一个开源的项目,很多细节都考虑到了,推荐大家使用~ ToDoList 帮你把要做的事情列出来,一项一项,类似思维导图. ...

  3. 解决键盘上符号打出来的和标着的不一样的错误&amp&semi;不能用ctrl&plus;space切换输入法错误

    0.右键输入法栏,点设置 1.增加”美式键盘“ 2.切换“默认键盘”为美式 3.删除“英式键盘” 4.高级键设置,改为ctrl+space

  4. 绘制FastMM内存分配流程图&lpar;小块内存分配&rpar;

    http://blog.csdn.net/henreash/article/details/38751353

  5. 《割绳子》《蜡笔物理学》《Contre Jour》《顽皮鳄鱼爱洗澡》等游戏用Box2D引擎实现物理部分的方法&lpar;转&rpar;

    从最热门游戏排行榜和flash游戏网站上,你能看到什么?许多2D游戏都有非常出色的物理学和美术设计.现在我们要学习那些游戏使用了什么物理学以及如何用Box2D制作它们. 除了知道是“什么”,更重要的是 ...

  6. &lbrack;bzoj4883&rsqb;&lbrack;Lydsy2017年5月月赛&rsqb;棋盘上的守卫

    来自FallDream的博客,未经允许,请勿转载, 谢谢. 在一个n*m的棋盘上要放置若干个守卫.对于n行来说,每行必须恰好放置一个横向守卫:同理对于m列来说,每列 必须恰好放置一个纵向守卫.每个位置 ...

  7. EF&plus;LINQ事物处理 C&num; 使用NLog记录日志入门操作 ASP&period;NET MVC多语言 仿微软网站效果&lpar;转&rpar; 详解C&num;特性和反射(一) c&num; API接受图片文件以Base64格式上传图片 &period;NET读取json数据并绑定到对象

    EF+LINQ事物处理   在使用EF的情况下,怎么进行事务的处理,来减少数据操作时的失误,比如重复插入数据等等这些问题,这都是经常会遇到的一些问题 但是如果是我有多个站点,然后存在同类型的角色去操作 ...

  8. 使用SatelliteMenu创建动画菜单

    一.GitHub地址:https://github.com/chenshouyin/SatelliteMenu 二.使用步骤: 第一步:在Android Studio中创建一个项目,然后在Androi ...

  9. opencv配置(转)

    1. 下载安装Opencv,去官网http://opencv.org/即可下载最新版本的Opencv,此处用的是Opencv 2.4.10 安装时傻瓜式的,最新版本的安装就是相当于解压到你指定的安装目 ...

  10. HAproxy-1&period;6&period;X 安装部署

    1. 源码包下载及安装 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 root@iZ23tsilmb7Z:/usr/local ...