C++ map、multimap、unordered_map

原文:C++ STL 各类容器基本使用

map与unordered_map相比:

map底层实现为红黑数,unordered_map底层实现为哈希表,两者均不能有重复的建,均支持[]运算符

map与multimap相比:

两者底层实现均为红黑树,但是multimap支持重复的键,不支持[]运算符。

 

内部实现机理不同
map: map内部实现了一个红黑树(红黑树是非严格平衡二叉搜索树,而AVL是严格平衡二叉搜索树),红黑树具有自动排序的功能,因此map内部的所有元素都是有序的,红黑树的每一个节点都代表着map的一个元素。因此,对于map进行的查找,删除,添加等一系列的操作都相当于是对红黑树进行的操作。map中的元素是按照二叉搜索树(又名二叉查找树、二叉排序树,特点就是左子树上所有节点的键值都小于根节点的键值,右子树所有节点的键值都大于根节点的键值)存储的,使用中序遍历可将键值按照从小到大遍历出来。
unordered_map: unordered_map内部实现了一个哈希表(也叫散列表,通过把关键码值映射到Hash表中一个位置来访问记录,查找的时间复杂度可达到O(1),其在海量数据处理中有着广泛应用)。因此,其元素的排列顺序是无序的。哈希表详细介绍

优缺点以及适用处
map:

优点:

有序性,这是map结构最大的优点,其元素的有序性在很多应用中都会简化很多的操作
红黑树,内部实现一个红黑书使得map的很多操作在lgn的时间复杂度下就可以实现,因此效率非常的高
缺点: 空间占用率高,因为map内部实现了红黑树,虽然提高了运行效率,但是因为每一个节点都需要额外保存父节点、孩子节点和红/黑性质,使得每一个节点都占用大量的空间

适用处:对于那些有顺序要求的问题,用map会更高效一些

 

unordered_map:

优点: 因为内部实现了哈希表,因此其查找速度非常的快
缺点: 哈希表的建立比较耗费时间
适用处:对于查找问题,unordered_map会更加高效一些,因此遇到查找问题,常会考虑一下用unordered_map
总结:

内存占有率的问题就转化成红黑树 VS hash表 , 还是unorder_map占用的内存要高。
但是unordered_map执行效率要比map高很多
对于unordered_map或unordered_set容器,其遍历顺序与创建该容器时输入的顺序不一定相同,因为遍历是按照哈希表从前往后依次遍历的
map和unordered_map的使用
unordered_map的用法和map是一样的,提供了 insert,size,count等操作,并且里面的元素也是以pair类型来存贮的。其底层实现是完全不同的,上方已经解释了,但是就外部使用来说却是一致的。

 

map元素的默认值(unordermap也一样)

当map内元素值为int类型或常量时,默认值为0。

当为String类型时,默认值不明,不显示。

    1. map内元素值为int类型
#include <iostream>
#include <map>
using namespace std;

int main(){
    map<int,int> table;

    table[1]=1;

    cout<<table[0]<<endl;
    cout<<table[1]<<endl;
    return 0;

}

运行结果:

 

 

 
map和multimap会自动排序,unordered_map不会
int main()
{
    map<int,int> a;
    multimap<int,int> b;
    unordered_map<int,int> c;
    a[1]=20;
    a[4]=30;
    a[7]=90;
    a[5]=10;
    a[2]=40;
    auto iter = a.begin();
    cout<<"result of map:"<<endl;
    while(iter!=a.end())
    {
        cout<<iter->first<<","<<iter->second<<endl;
        ++iter;
    }
    cout<<"result of multimap:"<<endl;
    b.insert(make_pair(1,20)); 
b.insert(make_pair(1,70));
b.insert(make_pair(
4,30)); b.insert(make_pair(7,90)); b.insert(make_pair(5,10)); b.insert(make_pair(2,40)); auto iter1 = b.begin(); while(iter1!=b.end()) { cout<<iter1->first<<","<<iter1->second<<endl; ++iter1; } cout<<"result of unordered_map:"<<endl; c[1]=20; c[4]=30; c[7]=90; c[5]=10; c[2]=40; auto iter2 = c.begin(); while(iter2!=c.end()) { cout<<iter2->first<<","<<iter2->second<<endl; ++iter2; } }

 

 

 

 

 

 

 

c++ stl multimap基本操作使用技巧详细介绍
C++ stl  Multimap 和C++ stl  map 很相似,但是MultiMap允许重复的元素。
C++ stl  Multimap的基本操作类成员函数列表介绍如下:

begin()返回指向第一个元素的迭代器
clear()删除所有元素
count()返回一个元素出现的次数
empty()如果multimap为空则返回真
end()返回一个指向multimap末尾的迭代器
equal_range()返回指向元素的key为指定值的迭代器对
erase()删除元素
find()查找元素
get_allocator()返回multimap的配置器
insert()插入元素
key_comp()返回比较key的函数
lower_bound()返回键值>=给定元素的第一个位置
max_size()返回可以容纳的最大元素个数
rbegin()返回一个指向mulitmap尾部的逆向迭代器
rend()返回一个指向multimap头部的逆向迭代器
size()返回multimap中元素的个数
swap()交换两个multimaps
upper_bound()返回键值>给定元素的第一个位置
value_comp()返回比较元素value的函数

#include <map>  
#include <string>  
#include <iostream>  
using namespace std;  
  
int main()  
{  
    ///1. 初始化  
    multimap<int, string> mapStudent;  
    multimap<int, string>::iterator iter, beg, end;  
      
    ///2. 添加元素  
    ///multimap不支持下标操作  
    mapStudent.insert(pair<int, string>(0, "student_one"));  
    mapStudent.insert(pair<int, string>(0, "student_one_copy"));///一对多  
    mapStudent.insert(pair<int, string>(1, "student_two"));  
    mapStudent.insert(pair<int, string>(5, "Fear Kubrick"));  
    mapStudent.insert(pair<int, string>(2, "Akemi Homura"));  
    mapStudent.insert(pair<int, string>(-1, "Eren Jaeger"));  
    mapStudent.insert(pair<int, string>(99, "lin"));  
    cout << mapStudent.size() << endl;  
    cout << endl;  
      
    ///3. 遍历  
    for (iter = mapStudent.begin(); iter != mapStudent.end(); iter++)  
        cout << iter->first << " " << iter->second << endl;  
    cout << endl;  
      
    ///4. 单键查询与范围查询  
    ///单键查询  
    int count = mapStudent.count(0);  
    iter = mapStudent.find(0);  
    for (int i = 0; i < count; i++, iter++)  
        cout << iter->first << " " << iter->second << endl;  
    cout << endl;  
    ///范围查询  
    beg = mapStudent.lower_bound(1);/// >=1  
    end = mapStudent.upper_bound(5);/// <=5  
    for (; beg != end; beg++)  
        cout << beg->first << " " << beg->second << endl;  
    cout << endl;  
      
    ///5. 删除  
    iter = mapStudent.find(1);  
    mapStudent.erase(iter);  
    cout << mapStudent.size() << endl;  
    for (iter = mapStudent.begin(); iter != mapStudent.end(); iter++)  
        cout << iter->first << " " << iter->second << endl;  
    cout << endl;  
      
    ///6. 判空与清空  
    if (!mapStudent.empty())  
        mapStudent.clear();  
}  

 

 

posted @ 2020-06-12 09:49  AI_ON  阅读(917)  评论(0)    收藏  举报