一、map简介:
- map是关联容器,它按照特定的次序(按照key来比较)存储由键值key和值value组合而成的元素。
- 在map中,键值key通常用于排序和惟一地标识元素,而值value中存储与此键值key关联的内容。键值key和值value的类型可能不同,并且在map的内部,key与value通过成员类型value_type绑定在一起,为其取别名称为pair:
typedef pair value_type; - 在内部,map中的元素总是按照键值key进行比较排序的。
- map中通过键值访问单个元素的速度通常比unordered_map容器慢,但map允许根据顺序对元素进行直接迭代(即对map中的元素进行迭代时,可以得到一个有序的序列)。
- map支持下标访问符,即在[]中放入key,就可以找到与key对应的value。
- map通常被实现为二叉搜索树(更准确的说:平衡二叉搜索树(红黑树))
二、map的使用:
- map的构造:
-
map() : 构造一个空的map
#include<iostream>
#include<map>
#include<string>
using namespace std;
int main()
{
// map 的构造
map<int, string> ismap;
return 0;
}
- map的迭代器:
-
(1) begin()和end() : begin:首元素的位置,end最后一个元素的下一个位置 (2)cbegin()和cend() :与begin和end意义相同,但cbegin和cend所指向的元素不能修改 (3)rbegin()和rend() : 反向迭代器,rbegin在end位置,rend在begin位置,其++和--操作与begin和end操作移动相反 (4)crbegin()和crend() :与rbegin和rend位置相同,操作相同,但crbegin和crend所指向的元素不能修改
#include<iostream>
#include<map>
#include<string>
using namespace std;
int main()
{
map<int, string> ismap;
//pair<int, string> v1 = { 1, "zhangsan" };
//pair<int, string> v2 = { 2, "lisi" };
//pair<int, string> v5 = { 5, "wuyan" };
//pair<int, string> v3 = { 3, "wangwu" };
//pair<int, string> v4 = { 4, "liuliu" };
//ismap.insert(v1);
//ismap.insert(v2);
//ismap.insert(v5);
//ismap.insert(v3);
//ismap.insert(v4);
//利用[]进行插入
ismap[1] = { "zhangsan" };
ismap[2] = { "lisi" };
ismap[5] = { "wuyan" };
ismap[4] = { "liuliu" };
ismap[3] = { "wangwu" };
auto it = ismap.begin();
while (it!= ismap.end())
{
cout << it->first << ":" << it->second << endl;
++it;
}
return 0;
}
}
- map的容量与访问:
-
(1)bool empty ( ) const :检测map中的元素是否为空,是返回true,否则返回false (2)size_type size() const :返回map中有效元素的个数 (3)mapped_type& operator[] (const key_type& k) :返回去key对应的value
#include<iostream>
#include<map>
#include<string>
using namespace std;
int main()
{
map<int, string> ismap;
pair<int, string> v1 = { 1, "zhangsan" };
pair<int, string> v2 = { 2, "lisi" };
pair<int, string> v3 = { 3, "wangwu" };
pair<int, string> v5 = { 3, "wangwu" };
pair<int, string> v4 = { 4, "liuliu" };
ismap.insert(v1);
ismap.insert(v2);
ismap.insert(v3);
ismap.insert(v4);
cout << ismap.empty() << endl;// 0
cout <<"size = "<< ismap.size() << endl;// 4:底层会自动删除相同内容,会对存储数据按照key排序
cout << ismap.count(3) << endl;//1
cout << ismap[1] << endl;//zhangsan
return 0;
}
- map中元素的修改:
-
(1)pair<iterator,bool> insert (const value_type& x ) :在map中插入键值对x,注意x是一个键值对,返回值也是键值对:iterator代表新插入元素的位置,bool代表释放插入成功 (2)void erase ( iterator position ) :删除position位置上的元素 (3)size_type erase ( constkey_type& x ) :删除键值为x的元素 (4)void erase ( iterator first,iterator last ) :删除[first, last)区间中的元素 (5)void swap(map<Key,T,Compare,Allocator>&mp ) :交换两个map中的元素 (6)void clear ( ) :将map中的元素清空 (7)iterator find ( const key_type& x):在map中插入key为x的元素,找到返回该元素的位置的迭代器,否则返回end (8)const_iterator find ( const key_type& x ) const:在map中插入key为x的元素,找到返回该元素的位置的const迭代器,否则返回cend (9)size_type count ( constkey_type& x ) const :返回key为x的键值在map中的个数,注意map中key是唯一的,因此该函数的返回值要么为0,要么为1,因此也可以用该函数来检测一个key是否在map中。
#include<iostream>
#include<string.h>
#include<map>
using namespace std;
int main()
{
map<int, string> ismap;
//pair<int, string> v1 = { 1, "zhangsan" };
//pair<int, string> v2 = { 2, "lisi" };
//pair<int, string> v5 = { 5, "wuyan" };
//pair<int, string> v3 = { 3, "wangwu" };
//pair<int, string> v4 = { 4, "liuliu" };
//ismap.insert(v1);
//ismap.insert(v2);
//ismap.insert(v5);
//ismap.insert(v3);
//ismap.insert(v4);
//1.利用[]进行插入
ismap[1] = { "zhangsan" };
ismap[2] = { "lisi" };
ismap[5] = { "wuyan" };
ismap[4] = { "liuliu" };
ismap[3] = { "wangwu" };
auto it = ismap.begin();
while (it != ismap.end())
{
cout << it->first << ":" << it->second << endl;
++it;
}
cout << "----------------------------" << endl;
//2.删除操作
ismap.erase(1);
ismap.erase(4);
auto it1 = ismap.begin();
//C++11遍历方式
for (const auto& e : ismap)
cout << e.first << ":" << e.second << endl;
cout << "----------------------------" << endl;
//3. 修改操作
ismap[2] = { "nihaoa" };
map<int, string> ::iterator it2 = ismap.begin();
for (; it2 != ismap.end(); ++it2)
{
cout << it2->first << ":" << it2->second << endl;
}
return 0;
}
三、multimap简单介绍:
- Multimaps是关联式容器,它按照特定的顺序,存储由key和value映射成的键值对<key, value>,其中多个键值对之间的key是可以重复的。
- 在multimap中,通常按照key排序和惟一地标识元素,而映射的value存储与key关联的内容。key和value的类型可能不同,通过multimap内部的成员类型value_type组合在一起,value_type是组合key和value的键值对:
typedef pair<const Key, T> value_type; - 在内部,multimap中的元素总是通过其内部比较对象,按照指定的特定严格弱排序标准对key进行排序的。
- multimap通过key访问单个元素的速度通常比unordered_multimap容器慢,但是使用迭代器直接遍历multimap中的元素可以得到关于key有序的序列。
- multimap在底层用二叉搜索树(红黑树)来实现。
- map于multimap区别:
multimap和map的唯一不同就是:map中的key是唯一的,而multimap中key是可以重复的.
三、以红黑树为底层结构封装map:
- 在map中封装一棵红黑树,进而对接口进行封装:
namespace ice
{
template<class K, class V>
class map
{
typedef pair<K, V> ValueType;
struct KeyOfValue
{
const K& operator()(const ValueType& v)
{
return v.first;
}
};
typedef RBTree<K, ValueType, KeyOfValue> RBTree;
public:
typedef typename RBTree::Iterator iterator;
public:
map(){}
iterator begin(){ return _t.Begin(); }
iterator end(){ return _t.End(); }
size_t size()const{ return _t.Size(); }
bool empty()const{ return _t.Empty(); }
V& operator[](const K& key)
{
return (*(_t.Insert(ValueType(key, V()))).first).second;
}
const V& operator[](const K& key)const;
pair<iterator, bool> insert(const ValueType& data) { return _t.Insert(data); }
void clear(){ _t.Clear(); }
iterator find(const K& key){ return _t.Find(key); }
private:
RBTree _t;
};
}
RBtree代码参考: