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

发布时间:2024年01月17日

一、基本概念

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);? 返回第一个小于给定关键字元素的迭代器

4、iterator map<T1,T2>::upper_bound(const T1&key);? 返回第一个大于给定关键字元素的迭代器

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等。在使用不同类型的元素时需要注意数据的兼容性和比较函数的设置。

文章来源:https://blog.csdn.net/qq_42106610/article/details/135632538
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。