map类与unordered_map类的区别

时间:2023-01-31 12:52:01

map类

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

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

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

  特性:1、有序性。这是map类最大的优点,许多时候有序性可以省去很多麻烦,较为适合处理有顺序要求的问题;

     2、唯一性。因为每个元素必须具有唯一的键值;

     3、红黑树。红黑树的结构使得效率提高,许多操作可以在lgn时间复杂度下完成,但也正是该结构使得空间利用率较高,每个节点都要保存相应的父节点与子节点等;

unordered_map类

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

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

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

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

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

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

当使用unordered_map时,输出如下:

  3,陈二

  2,李四

  6,李五

  5,张大

 

  2,李四

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

  2,李四

  3,陈二

  5,张大

  6,李五

 

  2,李四

具体细节也可以查看visual studio的帮助文档,对每一种方法都有很详细的代码解读。