一,map与set简介
map与set本质上便是一个关联容器,它们的底层都是一个叫做红黑树的数据结构。当然,所谓的红黑树又是一个二叉搜索树。所以追根溯源,map和set都是用二叉搜索树(红黑树)实现的容器。
在C++中,容器又分为序列化容器和关联容器。在这里的map和set就是关联容器。map和set中的元素是按关键字来保存和访问的。那什么是顺序容器呢?其实所谓的顺序容器就是我们曾经学过的list,vector,deque等容器。这些容器中的元素是按照它们在容器中的位置来访问和存储的。
map与set之间也是有差异的。map是一个key-value模型的容器,也叫键值对。而set是一个key-key模型的容器。接下来便来详细的介绍一下这两个容器的用法和特点。
二,map和set的用法和特点
1.map
首先来看看库里面的map定义:
在这个定义里面,我们首先知道的便是map是一个模板,因为我们看到了template,然后map还是一个类,因为在map前面有一个class。所以map便是一个模板类。
2.键值对
这个键值对是我们在学习map之前必须了解的一个东西。这个键值对是一个表示一一对应关系的一种数据结构。英文名是pair,在文档中长这样:
也是一个类模板。这个结构便是我们实现kv模型的关键一步。在map中也可以找到它的身影:
并且在这里面还可以看到在map里面第一个key的值是不能改的因为在key的前面有一个const修饰符,但是第二个value值是可以改的。在SGI版本的STL文件内,对于键值对的实现如下:
template <class T1, class T2> struct pair { typedef T1 first_type; typedef T2 second_type; T1 first; T2 second; pair(): first(T1()), second(T2()) {} pair(const T1& a, const T2& b): first(a), second(b) {} };
在这里不过多解释,我们知道就可以了。
3.map的各种功能函数
截图如下:
在这个截图里面可以看到map的功能函数还是很多的,像构造函数,各种迭代器函数,插入删除函数等等函数,map里面都有。而在些功能函数里面最屌的还是operator[ ]。这个函数可以帮我们实现使用key值来查找value值。比如这段代码:
#include<map> #include<iostream> using namespace std; int main() { map<string, int> Map; Map.insert(make_pair("string", 5)); cout << Map["string"] << " ";//使用字符串为下标 return 0; }
这段代码便是,要使用字符串为下标来寻找定位value值。真是不可思议啊,以前我们在用到[]时都是用数字加上[]来访问的,现在竟然变成了字符串来。现在便来看看它是如何实现的:
呐,看得懂吗?反正我是看不懂了。等我功力强一些再来拆解它把。
2.set
set和map一样也是一种树形关联容器。但是和map不一样的便是它是一个key-key类型的关联容器。set是不能插入重复元素的,但是set的变种兄弟mutil_set是可以支持插入重复元素的。现在来看看文档内的set模样:
可以发现,和map长得真像。现在再来看看set的功能函数:
可以看到set的功能函数和map的功能函数有很多是相同的,但是很明显缺少了一个[]。也就是说,set不支持[ ]。这是为什么呢?可以自己想想。