map是STL 的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据处理能力.
今天介绍的map,multimap,set,multiset的实现都采用了红黑树。(具体关于红黑树的相关,将在下篇博文与读者分享)
首先,我们来看看他们四个结构:
map
从上面便可以看出,他们俩(map和multimap)都是K/V的结构。
从上图便可以看出,他们都是K操作的。
unordered_map和unordered_set他们是C++11中才有的,请注意。他们俩的功能和map和set是差不到。但是,为什么会又要写两个不同的呢?
下面,我们先来看看它们的结构:
这里边便可以看出,他们的底层是哈希(具体关于哈希,我们以后再谈)。
首先,我们来说说C++11为什么要加入这两个函数,因为效率。红黑树的时间复杂度是O(lg N),而哈希的是O(1)。
这样效率便提高。
其实map,multimap,unordered_map的区别和set,multiset,unordered_set区别是一样的,所以,在此,本人只是粗浅的浅析map,multimap,unordered_map。
map
<span style="font-size:24px;">map<int,int> m; m.insert(pair<int ,int>(1,5)); m.insert(pair<int ,int>(4,2)); m.insert(pair<int ,int>(2,4)); m.insert(pair<int ,int>(3,3)); m.insert(pair<int ,int>(5,1)); m.insert(pair<int ,int>(1,5)); m.insert(pair<int ,int>(1,5)); m.insert(pair<int ,int>(1,5)); m.insert(pair<int ,int>(1,5)); map<int,int>::iterator il = m.begin(); while(il != m.end()) { cout<<il->first<<" " << il->second<<" "; cout<<endl; il++; }</span>
从上面便可以看出,它的输出是有序的,其实它是按照红黑树的中序遍历的,故而是有序的,并且,它是去除冗余的。
其次,我们再来看看它重载的[]
<span style="font-size:24px;">m[8] = 8 ; //在上述代码中加入这句代码</span>
结果为
结果为
便可以看出【】如果存在KEY便可以改变其中的vlaue的值,如果没有,它便会调用insert这个接口,详细的卡伊去看看STL中它的实现。
multimap
<span style="font-size:24px;"> multimap<int,int> ml; ml.insert(pair<int ,int>(1,5)); ml.insert(pair<int ,int>(4,2)); ml.insert(pair<int ,int>(2,4)); ml.insert(pair<int ,int>(3,3)); ml.insert(pair<int ,int>(5,1)); ml.insert(pair<int ,int>(1,5)); ml.insert(pair<int ,int>(1,5)); ml.insert(pair<int ,int>(1,5)); ml.insert(pair<int ,int>(1,5)); ml.insert(pair<int ,int>(1,5)); ml.insert(pair<int ,int>(1,5)); multimap<int,int>::iterator it = ml.begin(); while(it != ml.end()) { cout<<it->first<<" " << it->second<<" "; cout<<endl; it++; }</span>结果为:
排序,并且不除去冗余。其余的功能与map一样。
但是,请注意的是multimap并没有重载【】,这个值得注意,具体原因因为查了很多地方仍没有找到答案,故而在此求助,知道的可以留言。
unordered_map
<span style="font-size:24px;">unordered_map<int,int> ml; <span style="white-space:pre"> </span>ml.insert(pair<int ,int>(1,5)); <span style="white-space:pre"> </span>ml.insert(pair<int ,int>(4,2)); <span style="white-space:pre"> </span>ml.insert(pair<int ,int>(2,4)); <span style="white-space:pre"> </span>ml.insert(pair<int ,int>(3,3)); <span style="white-space:pre"> </span>ml.insert(pair<int ,int>(5,1)); <span style="white-space:pre"> </span>ml.insert(pair<int ,int>(1,5)); <span style="white-space:pre"> </span>ml.insert(pair<int ,int>(1,5)); <span style="white-space:pre"> </span>ml.insert(pair<int ,int>(1,5)); <span style="white-space:pre"> </span>ml.insert(pair<int ,int>(1,5)); <span style="white-space:pre"> </span> <span style="white-space:pre"> </span> <span style="white-space:pre"> </span>unordered_map<int,int>::iterator it = ml.begin(); <span style="white-space:pre"> </span>while(it != ml.end()) <span style="white-space:pre"> </span>{ <span style="white-space:pre"> </span>cout<<it->first<<" " << it->second<<" "; <span style="white-space:pre"> </span>cout<<endl; <span style="white-space:pre"> </span>it++; <span style="white-space:pre"> </span>} </span>结果如下:
可以看出,它可以去除冗余,但是,他并不能排序。
本文只是对map,multimap,unordered_map,set,multiset,unordered_set的粗略浅析,如有错误欢迎指正,也欢迎读者补充其他。