STL的map介绍

来源:互联网 发布:php隐藏下载地址 编辑:程序博客网 时间:2024/06/04 19:53

一:map是关联式容器,它提供一对一的映射。存储的数据有两个部分,一个是关键字,一个是值,其中关键字只能出现一次,而不同的关键字,可以有相同的值。map中用pair来存储这两个值的。pair是stl定义的一种数据结构,后面会有简述。map内部自建一颗红黑树,所有map里面的数据都是有序的。

二:方法

1.构造函数,map有6个构造函数。但是我们通常用map<type1,type2> m;这种方法来构造一个map实例。

2.数据插入,map通常用下面的三种方式插入数据。

   1),用insert方法插入pair数据。


void main( VOID ) 
{
      map<string,int> m;
      m.insert(pair<string,int>("sa",67));
      m.insert(make_pair<string,int>("sd",565));//用make_pair方法(函数)产生pair对象。
      map<string,int>::iterator it = m.begin();
      while(it!=m.end())
     {
         cout<<it->first<<" "<<it->second<<endl;
         it++;
     }
}

2,)用insert函数插入value_type数据。

void main( VOID ) 
{
   map<string,int> m;

    m.insert(map<string,int>::value_type("sd",5));    

    map<string,int>::iterator it = m.begin();
    while(it!=m.end())
    {
       cout<<it->first<<" "<<it->second<<endl;
        it++;
    }

其实这个方法和上面的本质上是一样的。因为valud_type 就是pair类型的,只是换个方法而已,可以通过cout<<typeid(map<string,int>::value_type).name()来获得value_type的类型,得到类型为

struct std::pair<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const ,int>说明是个struct pair类型的。

3,)通过重载[]来插入数据。

void main( VOID ) 
{
   map<string,int> m;
    cout<<typeid(map<string,int>::value_type).name()<<endl;
    m["ds"] = 4;
    m["ds"] = 10;
    map<string,int>::iterator it = m.begin();
   while(it!=m.end())
   {
     cout<<it->first<<" "<<it->second<<endl;
     it++;
   }
}

这种法式是通过重载[]来实现的,但是需要注意的是,这种法式和前两种有本质的区别,看下面的代码

    m.insert(pair<string,int>("ds",5));
   m.insert(pair<string,int>("ds",15));

当关键字相同的时候,不会改变他的值,也就是说在调用insert函数的时候,会检查,这个关键字是否存在了,如果存在,那么就不做任何操作。否则插入新的数据。
    m["ds"] = 4;
    m["ds"] = 10;

这种方式插入数据是不会做检查的,会直接在那个点上写上关键字和值,也就是说。ds项的值将是10.

3,数据遍历。

stl里的容器的遍历都是通过迭代器来遍历的。即便是用数组的方式,也是通过迭代器。数据遍历也有三种法式,1,向前迭代器,2,用反向迭代器,3,数组,第一种方式前面也就有说明。下面讲第二第三种,

     反向迭代器的方式

void main( VOID ) 
{
map<string,int> m;
m["ds"] = 4;
m["as"] = 10;
m.insert(pair<string,int>("cs",5));
m["bs"] = 123;
map<string,int>::reverse_iterator rit = m.rbegin();//从后面开始。
while(rit!=m.rend())
{
   cout<<rit->first<<" "<<rit->second<<endl;
   rit++;
}
}

这样是以相反的法式输出的。

    数组方式

void main( VOID ) 
{
map<string,int> m;
m["ds"] = 4;
m["as"] = 10;
m.insert(pair<string,int>("cs",5));
m["bs"] = 123;
map<string,int>::iterator it = m.begin();
for(int i=1;i<=m.size();i++)
{
   cout<<m[it->first]<<endl;//这里是用重载[]来得到value的。
   it++;
}
}

4       .数据的查找(包括判定这个关键字是否在map中出现)

在这里我们将体会,map在数据插入时保证有序的好处。

要判定一个数据(关键字)是否在map中出现的方法比较多,这里标题虽然是数据的查找,在这里将穿插着大量的map基本用法。

这里给出三种数据查找方法

第一种:用count函数来判定关键字是否出现,其缺点是无法定位数据出现位置,由于map的特性,一对一的映射关系,就决定了count函数的返回值只有两个,要么是0,要么是1,出现的情况,当然是返回1了

第二种:用find函数来定位数据出现位置,它返回的一个迭代器,当数据出现时,它返回数据所在位置的迭代器,如果map中没有要查找的数据,它返回的迭代器等于end函数返回的迭代器

5.数据清空,或判空

清空数据用clear函数,判断数据是否是空用empty函数。

6.数据删除。

数据删除用erase函数,这个函数有3个重载函数,用的时候,可随机而用。注意用这个函数后,相关的迭代器将会失效。

二:pair是stl里(目前我知道的)定义的一个struct,在msdn上查到如下的信息。

template<class Type1, class Type2>
   struct pair 
   {
   typedef Type1 first
_type;
   typedef Type2 second
_type
   Type1 first;
   Type2 second;
   pair( );
   pair(
      const Type1& 
__Val1
      const Type2& 
__Val2
   );
   template<class Other1, class Other2>
      pair(
         const pair<Other1, Other2>& 
_Right
      
);

与之相关的是make_pair函数。是个模板函数。

template<class Type1, class Type2>   pair<Type1, Type2> make_pair(      Type1 _Val1,      Type2 _Val2   );

三:关于map的迭代器,

对数据的插入,遍历,查找等操作,迭代器将不会失效,但是删除操作会失效。这与vector等序列式容器是不一样的。

三:效率

因为内部RB-TREE所以大多数的操作的时间复杂度都是O(logN),空间分析,在这些节点不保存数据的情况下就需要,左右孩子指针,指向父节点的指针,说明红黑的枚举值。

原创粉丝点击