STL中map的基本用法
pair
map中存储的基本数据类型是pair,首先我们简单介绍一下pair的基本结构
pair 定义在<map.h>中,
pair是有两个变量的结构体,变量的默认权限是public,都可以访问,只是first设置为const,不能修改键值
底层实现
结构定义
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 
 | 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) { }
 #ifdef	__STL_MEMBER_TEMPLATES
 template<class U1,class U2>
 pair(const pair<U1,U2>& p) :dirst(p.first),second(p.second){}
 #endif
 }
 
 
 | 
重载
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 
 | template <class T1, class T2>inline bool operator==(const pair<T1, T2>& x, const pair<T1, T2>& y) {
 return x.first == y.first && x.second == y.second;
 }
 
 
 template <class T1, class T2>
 inline bool operator<(const pair<T1, T2>& x, const pair<T1, T2>& y) {
 return x.first < y.first || (!(y.first < x.first) && x.second < y.second);
 }
 
 | 
成员函数 make_pair
| 12
 3
 4
 
 | template<class T1, classT2>inline pair<T1,T2> make_pair(const T1& x,const T2& y){
 return pair<T1,T2>(x,y);
 }
 
 | 
map
map存储的基本数据类型是pair,数据结构是RB-tree,可以理解为关联数组。可以使用键作为下标来获得相应的值。关联的本质在于元素的值与某个特定的键相关联。
map元素的键值是唯一的,multimap允许重复元素
map的insert必须是以pair为存储结构,当然也可以直接使用make_pair构造一个临时pair
构造函数
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 
 | 
 
 
 
 
 
 
 
 
 map<int,double>  m1;
 map<int,double,greater<int>> m2;
 map<int,double,less<int>> m3;
 
 
 
 map<int ,double>::iterator itm;
 
 | 
增加元素
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 
 |     pair<string, int> p;
 p.first = "zero", p.second = 0;
 m.insert(p);
 
 
 m.insert(make_pair("one", 1));
 
 
 m["two"]=3;
 
 std::cout<<m["three"];
 
 | 
基本属性获取
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 
 | class map {public:
 ...
 public:
 
 key_compare key_comp() const { return t.key_comp(); }
 
 value_compare value_comp() const { return value_compare(t.key_comp()); }
 
 
 
 iterator begin() { return t.begin(); }
 const_iterator begin() const { return t.begin(); }
 
 iterator end() { return t.end(); }
 const_iterator end() const { return t.end(); }
 
 
 reverse_iterator rbegin() { return t.rbegin(); }
 const_reverse_iterator rbegin() const { return t.rbegin(); }
 reverse_iterator rend() { return t.rend(); }
 const_reverse_iterator rend() const { return t.rend(); }
 
 
 bool empty() const { return t.empty(); }
 
 
 size_type size() const { return t.size(); }
 size_type max_size() const { return t.max_size(); }
 
 
 void swap(map<Key k, T t, Compare, Alloc>& x) { t.swap(x.t); }
 ...
 };
 template <class Key, class T, class Compare, class Alloc>
 inline void swap(map<Key, T, Compare, Alloc>& x,
 map<Key, T, Compare, Alloc>& y) {
 x.swap(y);
 }
 
 | 
重载
==,<
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 
 | class map {
 public:
 ...
 public:
 map(const map<Key, T, Compare, Alloc>& x) : t(x.t) {}
 map<Key, T, Compare, Alloc>& operator=(const map<Key, T, Compare, Alloc>& x)
 {
 t = x.t;
 return *this;
 }
 ...
 };
 template <class Key, class T, class Compare, class Alloc>
 inline bool operator==(const map<Key, T, Compare, Alloc>& x,
 const map<Key, T, Compare, Alloc>& y) {
 return x.t == y.t;
 }
 
 template <class Key, class T, class Compare, class Alloc>
 inline bool operator<(const map<Key, T, Compare, Alloc>& x,
 const map<Key, T, Compare, Alloc>& y) {
 return x.t < y.t;
 }
 
 | 
[]
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 
 | class map {public:
 ...
 public:
 
 
 
 T& operator[](const key_type& k) {
 return ( *(  (  insert(value_type(k, T()))   ).first)  ).second;
 }
 ...
 };
 
 | 
常用操作
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 
 | std::cout<<mm["1"]<<" "<<mm["2"]<<std::endl;
 std::swap(mm["1"],mm["2"]);
 std::cout<<mm["1"]<<" "<<mm["2"];
 
 
 iterator erase(iterator it);
 
 iterator erase(iterator first,iterator last)
 
 size_type erase(const Key&key);
 
 clear()
 
 
 
 
 size_type count(const Key& key )  const;
 
 
 
 iterator find(const Key& key);
 const_iterator find(const Key& key ) const;
 
 
 
 
 | 
补充1:
在STL中,map,set,multimap,multiset底层都是用红黑树实现,都是有序的
相关操作的复杂度
| 12
 3
 
 | 插入: O(logN)查看:O(logN)
 删除:O(logN)
 
 | 
hash_map, hash_set, hash_multimap, and hash_multiset
 上述四种容器采用哈希表实现,不同操作的时间复杂度为:
| 12
 3
 
 | 插入:O(1),最坏情况O(N)查看:O(1),最坏情况O(N)
 删除:O(1),最坏情况O(N)。
 
 | 
unordered_map 和 hash_map的内部结构都是用哈希表来实现,但是在C++11中,hash_map已经被舍弃了,最好建议使用unordered_map
更详细的相关区别: https://blog.csdn.net/chen134225/article/details/83106569
参考资料:
https://github.com/GritCS/STL/blob/master/30%20map.md