一、概述
1、是什么
map是一类关联式容器,关联的本质在于元素值与某个特定的键相关联。增删节点对迭代器影响很小,对于迭代器而言,不可修改键,只能修改其对应的值。map内部自建一棵红黑树,对内部元素有自动排序的功能。
红黑树:一种二叉查找树,此外在每个节点上增加一个存储位表示节点的颜色,可以是red,也可以是black。通过对一条从根到叶子节点的路径上各个节点着色方式的限制,红黑树确保没有一条路径会比其他路径长两倍,因此是接近平衡的。作为一个二叉查找树,满足二叉查找树的一般性质。
二叉查找树,即有序二叉树,有如下性质:
- 任意节点的左子树不空,则左子树上所有节点的值均小于它的跟节点的值
- 任意节点的右子树不空,则右子树上所有节点的值均大于它的跟节点的值
- 任意节点的左、右子树也分别是二叉查找树
- 没有键值相等的节点
二叉查找树高度为lgn,一般操作执行时间为O(logn),如果二叉查找树退化为一棵具有n个节点的线性链后,则这些操作最坏情况的运行时间为O(n)。而红黑树增加了着色和相关性质,是的红黑树相对平衡,从而保证了红黑树的查找、插入、删除的时间复杂度最坏为O(logn)。
红黑树性质:
- 每个节点要么是red,要么是black
- 跟节点是black
- 每个叶子结点都是black
- 如果一个节点是red,那么它的两个儿子都是black
- 对于任意节点而言,其到叶子结点的每条路径都包含相同数目的black节点
这5个性质保证了一棵有n个节点的红黑树始终保持logn的高度。
2、功能
首先,使用map需要包含头文件#include<map>。自动简历key-value的一一对应关系,key和value可以是任意类型,但是key的类型需要支持<操作符。由上述可知,查找的复杂度基本是logn,如果有1000个记录,则最多需要查询10次,如果有1000000个记录,最多需要查询20次。当然也有添加、删除、修改value、遍历等功能。
二、map的使用
1、插入
map<int, string> m_str;
pair<map<int, string>::iterator, bool> is_suc;
//map的插入有三种方式
//1、insert(pair<>)
is_suc = m_str.insert(pair<int, string>(2, "yuhy"));
//可以用is_suc判断是否插入成功
if(is_suc.second){
cout << "successful" << endl;
}else{
cout << "failed" << endl;
}
//2、insert (value_type)
m_str.insert(map<int, string>::value_type(5, "scott"));
//3、用数组方式插入数据
m_str[1] = "LiMing";
2、遍历
//遍历方式四种:
//1、for each
for(auto it : m_str){
cout << "key:" << it.first << ", value: