STL中的map学习笔记

来源:互联网 发布:mac如何画泳道图 编辑:程序博客网 时间:2024/05/21 21:35

map属于STL中的关联式容器,它所有的元素都是pair,同时拥有实值(value)和键值(key)。有没有感觉像hash,也是成对存在的。没错在STL中还有一种关联式容器叫hash_map,底层当然不用怀疑是用hashtable支持的。而map的底层是rbtree

看到rbtree你肯定就不难理解map所有的元素都会根据元素的键值自动被排序了吧。和set一样,map也不允许两个元素拥有相同的键值。几乎所有的map操作也都转调用rbtree的接口操作 。

map的迭代器问题,和list相似。对map进行插入删除操作,除被删除元素的迭代器失效后其他的操作之前的迭代器都依然有效(包括指针,引用)。那么通过迭代器修改元素的键值可以吗?通过迭代器修改元素的实值可以吗?答案是前者不可以,后者可以。因为map的内部是通过元素的键值进行排序的,修改元素的键值当然会破坏map的结构组织,所以不可通过元素的迭代器修改元素的键值。

来看看map是怎么同时保存一对值的。

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){}};

看完pair的结构体定义,你应该就知道了吧,map是通过pair把元素的键值和元素的实值绑定到一块,然后再添加到map中。

来看看map的构造函数
map(); // 默认构造函数
map(const map& m) // 拷贝构造函数
map(iterator begin, iterator end ); //区间构造函数
map(iterator begin, iterator end, const traits& _compare) //带比较谓词的构造函数
map(iterator begin, iterator end, const traits& _compare, const allocator& all) //带分配器

测试代码如下:

#include <iostream>using namespace std;#include <map>void main(){    map<int, int> map1;    map1.insert(pair<int, int>(1, 10));    map1.insert(pair<int, int>(2, 20));    map1.insert(pair<int, int>(2, 30));  //键值重复则添加不进去    map1[3] = 30;    map1[4] = 40;    map1[6] = 60;    map<int, int> map2(map1);    map<int, int>::iterator it = map1.begin();    map<int, int>::iterator it2 = map1.end();    map<int, int> map3(it, it2);    //map(iterator begin, iterator end, const traits& _compare) //带比较谓词的构造函数    //map(iterator begin, iterator end, const traits& _compare, const allocator& all) //带分配器    for (; it != it2; it++)    {        cout << it->first << " " << it->second << endl;    }    pair<int, int> val(5, 50);    map<int, int>::iterator temp;    temp = map1.insert(val).first;   //insert返回型别为pair。    cout << (*temp).second << endl;        //bool a = map1.insert(val).second;    //bool flg = map1.insert(pair<int,int>(7,70)).second;    cout << "---------------------------------------" << endl;    cout << map1.count(2) << endl;  //返回指定元素出现的次数,传入的是键值,结果非0即1    cout << "map1.size() = " << map1.size() << endl;    //关键字为1、2、3、4、5、6  以下为三种删除    map<int, int>::iterator it3 = map1.begin();    map1.erase(it3);    it = map1.begin();    it2 = ++it;    --it;    map1.erase(it, it2);  //删除区间[it-it2),注意是前闭后开    map1.erase(5);  //剩余关键字3、4、6    cout << "map1.size() = " << map1.size() << endl;      cout << "map1.max_size() = " << map1.max_size() << endl;  //178956970    //map1.clear();    if (map1.empty())     {        cout << "map1 is empty" << endl;    }    else        cout << "map1 is not empty" << endl;    //rbegin() 返回一个指向map尾部的逆向迭代器    //rend() 返回一个指向map头部的逆向迭代器    map<int, int>::reverse_iterator it4 = map2.rbegin();    for (; it4 != map2.rend(); it4++)    {        cout << it4->first << " " << it4->second << endl;    }    //对于关联式容器使用其提供的find函数搜索元素比使用stl算法find()更有效率    map<int, int>::iterator it5;    it5 = map2.find(2);    if (it5 == map2.end())    {        cout << "关键字为2的元素在map2中未找到\n";    }    else    {        cout << "关键字为2的元素在map2中成功找到\n";    }    it5->second = 100;    cout << "通过迭代器修改后值为 :" << it5->second << endl;    //it5->first = 12;}

运行结果:
这里写图片描述

通过map的迭代器修改其键值是编译不过的,但可以通过它的迭代器修改它的实值。

这里写图片描述

下面测试以下方法:
//lower_bound() 返回键值 >= 给定元素的第一个位置
//upper_bound() 返回键值>给定元素的第一个位置
//swap() 交换两个map

#include <iostream>using namespace std;#include <map>void main(){    map<int, int> map1;    for (int i = 1; i <= 10; i++)    {        map1[i] = i * 10;    }    cout << map1.lower_bound(5)->first<< endl;      cout << map1.lower_bound(5)->second << endl;      cout << map1.upper_bound(5)->first << endl;      cout << map1.upper_bound(5)->second << endl;    map<int, int> map2;    map2.insert(pair<int, int>(1, 11));    map2.insert(pair<int, int>(2, 22));    map2.insert(pair<int, int>(3, 33));    cout << "交换前----------------" << endl;    cout << "map1.size() = " << map1.size() << endl;    cout << "map2.size() = " << map2.size() << endl;    map1.swap(map2);  //交换两个map,两map的键值和实值类型必须都相同    cout << "交换后----------------" << endl;    cout << "map1.size() = " << map1.size() << endl;    cout << "map2.size() = " << map2.size() << endl;}

测试结果:
这里写图片描述

结束~~

原创粉丝点击