STL中的map学习笔记

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

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

结束~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值