C++ | STL 单映射容器map

目录

一.何为单映射容器map

二.map容器的使用方法


一.何为单映射容器map

在简绍这map容器之前我们先来看另一个概念——键值对。

所谓的键值对是由 键(key) 和 值(value) 两部分组成的,一个键对应一个值,值可以重复,但是键不能重复。例如我们可以将身份证号对应为键(key),而某个身份证号对应的名字称为值(value),而我们都知道身份证号是不可以重复的,人手一个,但是名字却可以重复。而我们所要简绍的map中的数据就是以键值对的形式存在的。

单映射容器map的底层都为红黑树,所需的头文件为#include<map>。

接着我们来看一下底层的二叉树具体是怎么存储map容器中的数据的

我们看到map底层二叉树的一个节点被分为3个域,分别是左孩子域,右孩子域和数据域(映射域),而这里的映射域中存放的就是结构体pair定义的映射关系,也就是我们上面提到过的键值对,我们来看一下结构体pair的类型。

#include<iostream>
#include<iterator>
#include<algorithm>
#include<map>

int main()
{
	std::map<int, int> mymap;//创建一个map容器
	std::cout <<typeid(std::map<int,int>::value_type).name()<< std::endl;
        return 0;
}

我们看到在结构体pair中,键(key)是常量,而值(value)是变量。

二.map容器的使用方法

#include<iostream>
#include<iterator>
#include<algorithm>
#include<map>

template<typename Container>
void Show(Container& con)
{
	typename Container::iterator it = con.begin();
	while (it != con.end())
	{
		std::cout << it->first << "-" << it->second << std::endl;
		it++;
	}
}

int main()
{
	std::map<int, int> mymap;//创建一个map容器

	std::pair<int, int> p1(1, 11);
	mymap.insert(p1);

	std::pair<int, int> p2(1, 1111);
	mymap.insert(p2);//没有处理  
	std::cout << "第一次打印:"<<std::endl;
	Show(mymap);
	
	std::map<int, int>::value_type val(2, 22);
	mymap.insert(val);
	

	mymap[3] = 33;//插入

	mymap[1] = 111;//修改

	std::cout << "第二次打印:" << std::endl;
	Show(mymap);

	//map 类中 find查询  二分查找  O(log2 n)
	std::map<int, int>::iterator fit = mymap.find(2);
	if (fit != mymap.end())
	{
		std::cout << "第三次打印:" << std::endl;
		std::cout << fit->first << fit->second << std::endl;
		//fit->first 代表迭代器所迭代的映射关系中 key  fit->second 代表迭代器所迭代的映射关系中 value
		mymap.erase(fit);
	}

	std::cout << "第四次打印:" << std::endl;
	Show(mymap);
	return 0;
}

 

其中

std::pair<int, int> p1(1, 11);
mymap.insert(p1);

这两句的意思是,首先利用结构体pair创建一个映射关系(键值对),其键(key)为1,值(value)为11,接着将这一映射关系(键值对)插入到map容器中。我们知道map的底层为红黑树,所以map容器中不存在定点插入,因为每插入一个数据,红黑树就要进行相应的调整。

std::pair<int, int> p2(1, 1111);
mymap.insert(p2);//没有处理 

我们知道,键值对中的键(key)必须唯一,前面我们已经将映射关系(键值对)1->11,插入到map容器中了,所以就算这时我们重新创建一个映射关系(键值对)1->11,并将它插入到map容器当中,系统也会将它忽略掉,不作任何处理,这一点我们可以从上面打印的结果中可以看到。

std::map<int, int>::value_type val(2, 22);
mymap.insert(val);

这是另一种向map容器中插入的方法,使用这种方法时,我们可以不必利用结构体pair创建映射关系,而是利用value_type做插入。

mymap[3] = 33;//插入

mymap[1] = 111;//修改

我们看到这两条语句大径相同,但各自最终的结果却是天壤地别。因为我们之前只向map容器中插入了键值对 1->11 和 2->22,而没有插入过键(key)为3的键值对,所以mymap[3]=33在这里的意思是向map容器中插入映射关系(键值对)3->33。因为之前已经插入过键值对1->11了,所以mymap[1]=111的意思是,将键值对1->11的值(value)11改为111,所以最后键(key)所对应的值变为了111。

std::map<int, int>::iterator fit = mymap.find(2);
if (fit != mymap.end())
{
	std::cout << "第三次打印:" << std::endl;
	std::cout << fit->first << fit->second << std::endl;
	//fit->first 代表迭代器所迭代的映射关系中 key  fit->second 代表迭代器所迭代的映射关系中 value
	mymap.erase(fit);
}

在这里map类中会提供一个查找函数find,时间复杂度为O(log2 n)因为是使用的是二分查找法,参数是要查找的键(key),例如这里我们利用find查找键(key)为2的键值对的位置,如果找到就将键(key)为2的键值对的位置传递给迭代器fit,如果找不到,即键(key)为2的键值对不存在,那么就把map容器的.end()位置传给迭代器fit。而 fit->first代表当前迭代器所迭代的映射关系中的键(key),fit->second代表当前迭代器所迭代的映射关系中的值(value)。而erase的意思是删除当前迭代器所迭代的键值对(映射关系)。

最后我们看到利用泛型算法Show打印的map容器中的数据都是从小到大排序的,这是因为map容器的底层为红黑树,红黑树是默认按中序遍历来对数据进行从小到大的排序的。

发布了88 篇原创文章 · 获赞 40 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/ThinPikachu/article/details/104997445