浅谈map与unordered_map的区别

转自:https://www.cnblogs.com/LDTSB-0101001/p/9749137.html

map类

  map是一种容器,内部元素由键值对组成,键与值的数据类型可以不同,键的值是唯一的(此处的值不是键值对中的值),用于自动排序数据值,排序方式是根据某种明确、严格的弱排序标准进行的,这种排序标准是由map内部的比较对象(即map::key_comp)指定的。使用时要引入#include <map>。

  在键——值这个映射关系中,元素数据值是可以更改的,但键值是常量,一旦确定无法随意更改。必须先删除与旧元素关联的键值,才能为新元素插入新键值。

  实现机理:map内部实现了一个红黑树(红黑树是非严格平衡二叉搜索树,而AVL是严格平衡二叉搜索树),红黑树具有自动排序的功能,因此map内部的所有元素都是有序的,红黑树的每一个节点都代表着map的一个元素。因此,对于map进行的查找,删除,添加等一系列的操作都相当于是对红黑树进行的操作。map中的元素是按照二叉搜索树(又名二叉查找树、二叉排序树,特点就是左子树上所有节点的键值都小于根节点的键值,右子树所有节点的键值都大于根节点的键值)存储的,使用中序遍历可将键值按照从小到大遍历出来。

  特性:1、有序性。这是map类最大的优点,许多时候有序性可以省去很多麻烦,较为适合处理有顺序要求的问题;   
                  2、唯一性。因为每个元素必须具有唯一的键值;
                  3、红黑树。红黑树的结构使得效率提高,许多操作可以在logn时间复杂度下完成,但也正是该结构使得空间利用率较高,每个节点都要保存相应的父节点与子节点等;

 

unordered_map类

  unordered_map顾名思义就是无序的,是用来替代hash_map类的,也是使用键值对来存储数据,但是这个数据是无序的,允许通过键值直接访问元素(在常数时间O(1)内)。

  实现机理:unordered_map内部实现了一个哈希表(也叫散列表,通过把关键码值映射到Hash表中一个位置来访问记录)。(哈希表是一个在时间和空间上做出权衡的经典例子。如果没有内存限制,那么可以直接将键作为数组的索引。那么所有的查找时间复杂度为O(1);如果没有时间限制,那么我们可以使用无序数组并进行顺序查找,这样只需要很少的内存。哈希表使用了适度的时间和空间来在这两个极端之间找到了平衡。只需要调整哈希函数算法即可在时间和空间上做出取舍。)

  特点:哈希表的存在使得查找速度极快(常数时间O(1)),但是哈希表的建立较为消耗时间较为适合处理查找问题;

 

       总结:哈希表较红黑树的空间占用率较高,但是执行效率要高于红黑树。

注意:虽然unordered_map是无序排列的,但是其遍历顺序与元素插入顺序是不同的,可以看如下代码:

#include <iostream>
#include <unordered_map>
#include <map>
#include <string>
using namespace std;
int main()
{
    //注意:C++11才开始支持括号初始化
    unordered_map<int, string> myMap={{ 5, "张大" },{ 6, "李五" }};//使用{}赋值
    myMap[2] = "李四";  //使用[ ]进行单个插入,若已存在键值2,则赋值修改,若无则插入。
    myMap.insert(pair<int, string>(3, "陈二"));//使用insert和pair插入
    //遍历输出+迭代器的使用
    auto iter = myMap.begin();//auto自动识别为迭代器类型unordered_map<int,string>::iterator
    while (iter!= myMap.end())
    {
        cout << iter->first << "," << iter->second << endl;
        ++iter;
    }
    //查找元素并输出+迭代器的使用
    auto iterator = myMap.find(2);//find()返回一个指向2的迭代器
    if (iterator != myMap.end())
        cout << endl<< iterator->first << "," << iterator->second << endl;
    system("pause");
    return 0;
}

当使用unordered_map时,输出如下:

  3,陈二

  2,李四

  6,李五

  5,张大

 

  2,李四

当使用的是map时,输出如下:

  2,李四

  3,陈二

  5,张大

  6,李五

 

  2,李四

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值