介绍set和map容器

本文详细介绍了STL中的关联式容器,如set、map、multiset和multimap,包括它们的定义、特点(如键值对、树形结构、排序和唯一性)、常用操作(构造、迭代器、容量和常用操作)以及简单示例。着重强调了这些容器在数据存储和查找方面的优势和特性。
摘要由CSDN通过智能技术生成


在介绍set和map容器前先了解什么是关联式容器和键值对

1.什么是关联式容器

在初始阶段我们所学的STL容器当中,像vector,list,stack,queue等都是序列式容器,因为在其底层为线性序列的数据结构,里面储存的元素本身。那么什么是关联式容器呢?
关联式容器也是用来存储数据的,与序列式式容器不同的是,其里面存储的是<key,value>结构的键值对,在数据检索时比序列式容器效率更高

2.什么是键值对

用来表示具有一一对应关系的一种结构,该结构种=中一般只包含两个成员变量key和value,key代表键值,value表示与key对应的信息。就像字典那样,一个英语单词对应着一个中文释义,那么我们可以是英语单词和中文释义是一一对应的关系,可以通过该单词找到与其对应的中文释义。

3.树形结构的关联式容器

在STL当中一共实现两种不同的结构管理式容器:树形结构与哈希结构。树型结构的关联式容器主要有4种:map、set、multimap、multiset。他们的共同特点:使用红黑树作为底层数据结构,容器中的元素是一个有序的序列。

3.1set

set
set

1.set是按照一定次序存储元素的容器
2.在set中,元素的value也标识它(value就是key,类型为T),并且每个value必须是唯一的。set中的元素不能再容器中修改(元素总是const),但是可以从容器中插入或是删除它们。
3.再内部,set中的元素总是按照内部比较对象(类型比较)所指示的特定严格排序准则进行排序。
4.set容器通过key访问单个元素的速度通常比unordered_set慢,但是它们允许根据顺序对子集进行直接迭代
5.set咋底层是用红黑树实现的

注意:

1.与map/multimap不同,map/multimap中存储的真正的键值对<key,value> ,set中只放value,但在底层实际放的是由<value,value> 构成的键值对
2.set中插入元素时,只需要插入value即可,不需要构造键值对
3.set中的元素不可重复(由此可以用set进行去重)
4.使用set的迭代器遍历set中的元素,可以得到有序的序列(底层为搜索二叉树(红黑树))
5.set中的元素默认按照小于来比较
6.set查找某个元素,时间复杂度为 l o g n log n logn
7.set中的元素不允许修改(如果修改了会改变红黑树的结构)

3.1.2set的使用

set的构造

分别为
构造空的set
迭代器构造
拷贝构造
set的构造

set的迭代器

set的迭代器

set的容量

set的容量

set的常用操作

set的常用操作
set的常用操作

set的简单使用
#include <set>
#include <vector>
#include <iostream>
using namespace std;

int main()
{
    vector<int> v({ 2,3,1,5,6,3,2,4,5,1,9,0 });
    //利用迭代器构造set
    set<int> s(v.begin(), v.end());
    for (auto& x : s)
        cout << x << ' ';
    //打印结果0 1 2 3 4 5 6 9
    //可以看到set是具有去重操作的
    cout << endl;
    //set迭代器的使用
    set<int>::iterator it = s.begin();
    for (; it != s.end(); ++it)
        cout << *it << ' ';
    cout << endl;
    //打印结果0 1 2 3 4 5 6 9
    return 0;
}

3.2 map

map
map
key表示 键值对中key的类型(相当于字典中的英文单词)
value表示 键值对中value的类型 (相当于英文单词对应的中文)
compare:比较器的类型,map中的元素是按照key进行比较的,缺省情况下就是按照小于来比较,一般情况下(内置元素)该参数不需要传递,如果无法比较时(自定义类型),需要用户直接写一个比较规则
Alloc:空间配置器

map的构造

map的构造

map的迭代器

map的迭代器

map的容量

map的容量

map的常用操作

map的常用操作
map的常用操作

map的使用

#include <map>
#include <string>
#include <iostream>
#include <vector>
using namespace std;
int main()
{
    vector<pair<string, string>> vp({{ "apple","苹果" },{ "yui", "结衣"} , { "man", "男人" } });
    map<string, string> d(vp.begin(), vp.end());//构造map
    for (auto& x : d)
        cout << x.first << ":" << x.second << " ";
    cout << endl;
    //打印结果  apple:苹果 man:男人 yui:结衣 ,会根据key来进行排序
    pair<string, string> p("cat", "猫");
    d.insert(p);//map的插入
    for (auto& x : d)
        cout << x.first << ":" << x.second << " ";
    cout << endl;
    //打印结果:apple:苹果 cat:猫 man:男人 yui:结衣
    d.erase("apple");//map的删除
    for (auto& x : d)
        cout << x.first << ":" << x.second << " ";
    cout << endl;
    //打印结果:cat:猫 man:男人 yui:结衣
    //如果删除没有的key呢?
    d.erase("apple");//apple已删除
    for (auto& x : d)
        cout << x.first << ":" << x.second << " ";
    cout << endl;
    //打印结果:cat:猫 man:男人 yui:结衣    //如果已经删除那么就也不会有什么影响
    //下面介绍map最重要的功能:[]
    //利用[],我们可以自由的对map进行插入和删除
    d["haha"] = "哈哈";
    for (auto& x : d)
        cout << x.first << ":" << x.second << " ";
    cout << endl;
    //cat:猫 haha:哈哈 man:男人 yui:结衣
    return 0;
}

结论:
1.map中的元素为键值对
2.map中的key是唯一的且不能修改
3.map利用迭代器遍历可以得到一个有序的序列
4.map支持[]的重载

3.3multiset

multiset

  1. multiset是按照特定顺序存储元素的容器,其中元素是可以重复的。
  2. 在multiset中,元素的value也会识别它(因为multiset中本身存储的就是<value, value>组成 的键值对,因此value本身就是key,key就是value,类型为T).
    multiset元素的值不能在容器中进行修改(因为元素总是const的),但可以从容器中插入或删除。
  3. 在内部,multiset中的元素总是按照其内部比较规则(类型比较)所指示的特定严格弱排序准则 进行排序。
  4. multiset容器通过key访问单个元素的速度通常比unordered_multiset容器慢,但当使用迭代器遍历时会得到一个有序序列。
  5. multiset底层结构为二叉搜索树(红黑树)。

multiset和set最大的区别就是multiset的元素是可以重复的。multiset的头文件也在#include <set>
multiset的简单使用

#include <set>//multiset也在其中
#include <vector>
#include <iostream>
using namespace std;

int main()
{
    vector<int> v({ 2,3,1,5,6,3,2,4,5,1,9,0 });
    //利用迭代器构造multiset
    multiset<int> s(v.begin(), v.end());
    for (auto& x : s)
        cout << x << ' ';
    //打印结果0 1 1 2 2 3 3 4 5 5 6 9
    //可以看到multiset没有去重操作的
    cout << endl;
    //multiset迭代器的使用
    multiset<int>::iterator it = s.begin();
    for (; it != s.end(); ++it)
        cout << *it << ' ';
    cout << endl;
    //打印结果0 1 1 2 2 3 3 4 5 5 6 9

    cout<<s.count(1);//计算容器是对应元素的个数
    //打印结果:2
    return 0;
}

3.4 multimap

multimap
multimap

  1. Multimaps是关联式容器,它按照特定的顺序,存储由key和value映射成的键值对<key, value>,其中多个键值对之间的key是可以重复的。
  2. 在multimap中,通常按照key排序和惟一地标识元素,而映射的value存储与key关联的内 容。key和value的类型可能不同,通过multimap内部的成员类型value_type组合在一起,value_type是组合key和value的键值对:
    typedef pair<const Key, T> value_type;
  3. 在内部,multimap中的元素总是通过其内部比较对象,按照指定的特定严格弱排序标准对 key进行排序的。
  4. multimap通过key访问单个元素的速度通常比unordered_multimap容器慢,但是使用迭代 器直接遍历multimap中的元素可以得到关于key有序的序列。
  5. multimap在底层用二叉搜索树(红黑树)来实现。

同样multimap和map最大的区别就是允许key重复,同时取消了[]的重载(多个key限制了[]的重载)。
在这里插入图片描述

  • 19
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Yui_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值