C++——STL标准模板库——容器详解——map

本文详细介绍了C++STL中的map容器,包括其基本概念、构造函数、成员函数以及使用过程中的优点、缺点和注意事项,重点讲解了map的自动排序、键值对、迭代器操作等内容。
摘要由CSDN通过智能技术生成

一、基本概念

1、map容器是STL中的一种具备自动排序功能的关联式容器。它提供了一对一的数据处理能力(其中第一个称为关键字,相当于索引,每个关键字在map中唯一,也是排序的主要依据;第二个称为该关键字的值,可以是任意类型),维护数据的对象是pair类型的键值对。pair<Key_type,Velue_type>,键值对的键和值可以是任意类型,一般键为string类型或者int类型,方便维护。

2、pair类型叫做对组,底层是模板结构体,提供两个模板参数。也就是pair<Type1,Type2>,模板参数列表中的参数可以是任意类型。用pair<T1,T2>::first读取第一个值,pair<T1,T2>::second读取第二个值。

3、map底层结构是红黑树(一种非严格意义上的平衡二叉树),这颗树具有对数据自动排序的功能,所以在map内部所有的数据都是有序的。并且不会存在重复关键字。

4、multimap和map具备同样的功能,但允许容器内出现重复关键字。

二、构造函数

1、map<T1,T2> m;                                        默认构造函数

2、map<T1,T2> m(iterator first,iterator last); 区间构造函数,需要提供存储键值对的容器迭代器

3、map<T1,T2> m(map<T1,T2>& other);      复制构造函数

4、map<T1,T2> m(map<T1,T2>& other);      移动构造函数

5、map<T1,T2> m(initializer_list& _list);        初始化列表构造函数

6、map<T1,T2,Key_Compare> m;                 自定义排序方式构造函数

map和set一样通过模板参数列表自定义排序方式。编译器默认内置数据类型例如int、double、string均为递增排序,需要递减排序或者关键字为自定义数据时,必须添加自定义排序类型。同样提供了多种重载,需根据实际情况灵活选用。

三、成员函数

(一)迭代器相关函数

1、iterator map<T1,T2>::begin();        返回容器第一个元素位置迭代器

2、iterator map<T1,T2>::end();           返回容器最后一个元素后面一个位置的迭代器

3、iterator map<T1,T2>::rbegin();       返回最后一个元素位置迭代器

4、iterator map<T1,T2>::rend();          返回第一个元素前面一个位置的迭代器

cbegin()、cend()、crbegin()、crend()    分别返回以上4种的常量迭代器

(二)大小相关函数

1、size_t map<T1,T2>::size();                                返回容器当前元素数量

2、size_t map<T1,T2>::max_size();                       返回容器理论上最大容纳元素数量

3、bool map<T1,T2>::empty();                               判断容器是否为空

(三)访问函数

1、const T2& map<T1,T2>::at(const T1&key);         返回索引key对应元素的常引用

2、T2& map<T1,T2>::at(const T1&key);                   返回索引key对应元素的引用

3、T2& map<T1,T2>::operator[](const T1&key)       下标符号[]重载,返回索引对应元素引用

以上3种访问函数传入参数均为关键字,而不是下标。当容器中关键字不存在时会出现出界问题。所以在使用前务必确认map容器中存在关键字,才可作为索引值传入。

(四)插入函数

插入元素必须为键值对,同样map元素调用插入函数,返回了对组<iterator,bool>,multimap调用插入函数返回迭代器iterator

1、insert(const pair<T1,T2>&value);                                        复制插入

      例1  insert(pair<T1,T2>(T1_value,T2_value);                           

      例2  insert(make_pair(T1_value,T2_value);                             

      例3  insert(map<T1,T2>::value_type(T1value,T2_value);         

2、insert(iterator pos,const pair<T1,T2>&value); 指定位置插入,其实指定位置没用,返回的迭代器还是指向排序后该元素的位置。

3、inset(initializer _list);                                        插入初始化列表,这个列表是pair类型的列表

4、insert(itrator first,itertor last);                            插入区间,提供的迭代器必须是储存相同pair类型的容器迭代器

5、insert(const pair<T1,T2>&&value);                  移动插入只移动关键字,不移动值

6、emplace(pair<T1,T2>&&value);                       在容器内构造元素

7、map<T1,T2>::operator[](key);                        此方法不稳定,当map容器内不存在关键字key时,会自动添加该关键字的键值对。

(五)删除函数

1、size_t map<T1,T2>::erase(const T1&key);                     按关键字删除元素,返回删除数量;

2、iterator map<T1,T2>::erase(const_iterator&where);       删除指定位置元素,返回该位置迭代器

3、iterator map<T1,T2>::erase(iterator first,iterator last);    按区间删除元素,返回起始位置迭代器

4、void map<T1,T2>::clear()                                                清空容器

(六)查找函数

1、iterator map<T1,T2>::find(const T1&key);     查找关键字,返回迭代器

2、size_t map<T1,T2>::count(const T1&key);    返回给定关键字的数量,map容器一般返回1或0

3、iterator map<T1,T2>::lower_bound(const T1&key); 

      iterator map<T1,T2>::upper_bound(const T1&key);  

        同set容器

5、pair<it,it> map<T1,T2>::equal_range(const T1&key); 返回给定关键字以内的区间

四、使用注意事项

(一)优点

1、数据结构采用红黑树,自身是有序的,插入数据时会自动排序。

2、内部结构采用红黑树,时间复杂度低,效率高。

3、索引方便,可以通过下标key方便的进行存取。

4、所有元素都会根据元素的键值自动排序。

5、不能通过map的迭代器改变键值。因为键值关系搞map元素的排列规则,任意改变map键值,将会严重破坏map组织,修改元素的实值是可以的。

6、在对容器元素进行新增或删除操作时,操作之前的所有迭代器,在操作完成后,依然有效;被删除的那个元素的迭代器无效。

(二)缺点

1、map内部采用红黑数实现,需要额外空间保存节点,会占用多余的空间,典型的以“空间换时间”。

2、使用at()索引时,要确定容器内存在传入的关键字,否则会抛出异常;使用[]索引时,如果容器内没有传入关键字,容器会自动添加改关键字的键值对。

(三)使用注意事项

1、map容器中的元素是pair类型,每个元素包含两个部分:键(key)和值(value)。键是唯一的,而值可以是重复的。在map中不能插入具有相同键的元素。若需要插入相同键的元素,可以使用multimap。

2、map容器的迭代器是双向的,这意味着在遍历过程中删除元素可能会导致未定义的行为。因此,在遍历过程中不应该删除元素。如果需要在遍历过程中删除元素,可以先将需要删除的元素保存下来,遍历完成后再进行删除。

3、map容器中的元素是按照键的顺序进行排序的,因此在使用map容器时需要注意键的类型和比较函数。如果需要自定义比较函数,可以使用map容器的比较函数适配器进行设置。

4、map容器的查找操作的时间复杂度为O(log n),其中n是map容器中元素的数量。因此,在处理大量数据时,使用map容器可以提高查找效率。但是需要注意的是,由于map容器需要维护元素的顺序,因此在插入和删除元素时可能会比其他容器慢一些。

5、map容器可以用于存储不同类型的元素,例如int和string等。在使用不同类型的元素时需要注意数据的兼容性和比较函数的设置。

  • 19
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值