C++ STL之map映照容器

map映照容器所处理的元素数据,与数据库的具有键值的记录非常相似,由一个键值和其他若干数据(映照数据)组成,键值和映照数据之间,可建立一个数学上的映照关系,由此而得映照容器的名称。**容器的数据结构同样是采用红黑树进行管理,插入的键值不允许重复,**所使用的节点元素的比较函数只对元素的键值进行比较,元素的各项数据可通过键值检索出来。

  1. map技术原理
    下图所示是map容器的一个元素的数据组成,可通过pair封装成一个结构对象。map容器做的,就是将这个pair对象插入到红黑树,完成一个元素的添加。同时,也要提供一个仅使用键值进行比较的函数对象,将它传递给红黑树。由此,可利用红黑树的操作,将map元素数据插入到二叉树中的正确位置,也可以根据键值进行元素的删除和检索。
    C++ STL之map映照容器_第1张图片
  2. map应用基础
    2.1创建map对象

利用默认的less函数对象和内存分配器,创建一个没有任何元素的map对象。例如下面一行代码创建了一个空的map对象m,m的键值类型为char,元素的映照数据类型为int,键值的比较函数对象为greaterps:greater是按照键值将映照数据从大到小排列,没写就默认从小到大,即比较函数对象为less。
map> m;
还有几种方式,后面有遇到再提
2.2元素的插入和删除
除了可以用insert函数将整个元素数据进行插入外,常用map容器的数组 “[]” ,显示地为不同键值赋予内容(映照数据)
不多说直接上代码:

#include 
#include 
#include 
#include
using namespace std;
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    map m1;
    map::iterator i;
    m1["apple"] = 3.6f;
    m1["orange"] = 3.2f;
    m1["banana"] = 1.8f;
    cout << "苹果价格:" << m1["apple"] << endl;
    cout << "橘子价格:" << m1["orange"] << endl;
    cout << "香蕉价格:" << m1["banana"] << endl;
    m1.erase("apple");                  //删除键值为apple的映照数据
    cout << "苹果价格:" << m1["apple"] << endl;
    return a.exec();
}

运行结果:
C++ STL之map映照容器_第2张图片
2.2元素的遍历访问和反向遍历
除了利用键值的数组方式来访问元素外,经常使用map容器的迭代器进行访问或反向遍历。

#include 
#include 
#include 
#include
using namespace std;
struct StudentInfo{        //定义学生信息的结构体
    char *name;
    int age;
    char *addr;
};
struct StudentRecord{      //学生记录结构体
    int id;                //学号作为键值
    StudentInfo sf;          //学生信息作为映照数据
};
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    StudentRecord srArray[] = {   //插入三条数据
        {1,"李强",21,"北京"},
        {2,"王文",26,"上海"},
        {3,"张三",19,"深圳"}
    };
    map m;
    for(int j=0;j<3;j++)
    {
        m[srArray[j].id] = srArray[j].sf;
    }
    map::iterator i,iend;
    iend=m.end();
    cout << "学号 " << "名字 " << "年龄 " << "地址 " << endl;
    for(i=m.begin();i!=iend;i++)
    {
        cout << (*i).first <<"   " << (*i).second.name << "   " << (*i).second.age << "   " << (*i).second.addr << endl;
    }
    cout << "反向遍历后:" << endl;
    map::reverse_iterator ri,rend;
    rend=m.rend();
    for(ri=m.rbegin();ri!=rend;ri++)
    {
        cout << (*ri).first <<"   " << (*ri).second.name << "   " << (*ri).second.age << "   " << (*ri).second.addr << endl;
    }
    return a.exec();

运行结果:
C++ STL之map映照容器_第3张图片
2.3元素的搜索
利用map提供的find函数,可搜索出具有某一键值的元素。

#include 
#include 
#include 
#include
using namespace std;
struct StudentRecord{        //定义学生记录结构体
    struct StudentInfo{
        char *name;
        int age;
        char *addr;
    };
    StudentRecord(int id_,char *name_,int age_,char *addr_)
    {
        id=id_;
        sf.name = name_;
        sf.age = age_;
        sf.addr = addr_;
    }
    int id;
    StudentInfo sf;
};
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    typedef map studentmap;    //定义一个map的对象m
    studentmap m;
    pair p;       //p用来判断是否插入成功
    //插入第一条数据
    StudentRecord student1 =StudentRecord(1,"娇娇",18,"上海");
    pair pairStudent1(student1.id,student1.sf);
    p=m.insert(pairStudent1);
    if(!p.second)
    {
        cout << "插入学生失败:" << endl
             << student1.id << " "
             << student1.sf.name << " "
             << student1.sf.age << " "
             << student1.sf.addr << endl;
    }
    //插入第二条数据
    StudentRecord student2 =StudentRecord(2,"阿明",16,"北京");
    pair pairStudent2(student2.id,student2.sf);
    p=m.insert(pairStudent2);
    if(!p.second)
    {
        cout << "插入学生失败:" << endl
             << student2.id << " "
             << student2.sf.name << " "
             << student2.sf.age << " "
             << student2.sf.addr << endl;
    }
    //插入第三条数据
    StudentRecord student3 =StudentRecord(3,"啊亮",21,"深圳");
    pair pairStudent3(student3.id,student3.sf);
    p=m.insert(pairStudent3);
    if(!p.second)
    {
        cout << "插入学生失败:" << endl
             << student3.id << " "
             << student3.sf.name << " "
             << student3.sf.age << " "
             << student3.sf.addr << endl;
    }
    //插入键值重复的学生记录,则插入失败
    StudentRecord student4 =StudentRecord(3,"多多",23,"广州");
    pair pairStudent4(student4.id,student4.sf);
    p=m.insert(pairStudent4);
    if(!p.second)
    {
        cout << "插入学生失败:" << endl
             << student4.id << " "
             << student4.sf.name << " "
             << student4.sf.age << " "
             << student4.sf.addr << endl;
    }
    //记录搜索
    studentmap::iterator i=m.find(2);
    cout << "搜索出学号为2的记录:" << endl
         << (*i).first << " "
         << (*i).second.name << " "
         << (*i).second.age << " "
         << (*i).second.addr << endl;
    return a.exec();
}

运行结果:
C++ STL之map映照容器_第4张图片
2.4补充
multimap多重映照容器,和map一样都是使用红黑树对元素进行插入等操作,但是multimap允许具有重复键值的元素插入容器。正是由于元素键值的重复插入,使得数组操作符“[]”利用键值来访问失去意义,因此multimap没有定义数组方式的"[]"操作运算。

你可能感兴趣的:(C++)