admin管理员组

文章数量:1487745

介绍set和map容器

在介绍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查找某个元素,时间复杂度为

log n

7.set中的元素不允许修改(如果修改了会改变红黑树的结构)

3.1.2set的使用
set的构造

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

set的构造
set的迭代器
set的迭代器
set的容量
set的容量
set的常用操作
set的常用操作
set的常用操作
set的简单使用
代码语言:javascript代码运行次数:0运行复制
#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的使用
代码语言:javascript代码运行次数:0运行复制
#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的简单使用

代码语言:javascript代码运行次数:0运行复制
#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限制了[]的重载)。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。 原始发表:2024-10-15,如有侵权请联系 cloudcommunity@tencent 删除容器存储mapset排序

本文标签: 介绍set和map容器