unordered_map 与 map 的对比(转)

unordered_map和map类似,都是存储的key-value的值,可以通过key快速索引到value。不同的是unordered_map不会根据key的大小进行排序,

存储时是根据key的hash值判断元素是否相同,即unordered_map内部元素是无序的,而map中的元素是按照二叉搜索树存储,进行中序遍历会得到有序遍历。

所以使用时map的key需要定义operator<。而unordered_map需要定义hash_value函数并且重载operator==。但是很多系统内置的数据类型都自带这些,

那么如果是自定义类型,那么就需要自己重载operator<或者hash_value()了。

1.结论

结论:如果需要内部元素自动排序,使用map,不需要排序使用unordered_map

运行效率方面:unordered_map最高,而map效率较低但 提供了稳定效率和有序的序列。

占用内存方面:map内存占用略低,unordered_map内存占用略高,而且是线性成比例的。

需要无序容器,快速查找删除,不担心略高的内存时用unordered_map;有序容器稳定查找删除效率,内存很在意时候用map。

2.原理

map的内部实现是二叉平衡树(红黑树);hash_map内部是一个hash_table一般是由一个大vector,vector元素节点可挂接链表来解决冲突,来实现.

hash_map其插入过程是:

  1. 得到key
  2. 通过hash函数得到hash值
  3. 得到桶号(一般都为hash值对桶数求模)
  4. 存放key和value在桶内。

其取值过程是:

  1. 得到key
  2. 通过hash函数得到hash值
  3. 得到桶号(一般都为hash值对桶数求模)
  4. 比较桶的内部元素是否与key相等,若都不相等,则没有找到。
  5. 取出相等的记录的value。

hash_map中直接地址用hash函数生成,解决冲突,用比较函数解决。

3.性能特点

非频繁的查询用map比较稳定;频繁的查询用hash_map效率会高一些,c++11中的unordered_map查询效率会更高一些但是内存占用比hash_map稍微大点。unordered_map 就是 boost 里面的 hash_map 实现。

其实,stl::map对于与java中的TreeMap,而boost::unordered_map对应于java中的HashMap。
python中的map就是hashmap实现的,所以查询效率会比C++的map查询快。(java,python官方版的虚拟机都是用C语言实现的,所以内部的思想和方法都是通用的。)

若考虑有序,查询速度稳定,容器元素量少于1000,非频繁查询那么考虑使用map。
若非常高频查询(100个元素以上,unordered_map都会比map快),内部元素可非有序,数据大超过1k甚至几十万上百万时候就要考虑使用unordered_map(元素上千万上亿时4GB的内存就要担心内存不足了,需要数据库存储过程挪动到磁盘中)。
hash_map相比unordered_map就是千万级别以上内存占用少15MB,上亿时候内存占用少300MB,百万以下都是unordered_map占用内存少,
且unordered_map插入删除相比hash_map都快一倍,查找效率相比hash_map差不多,或者只快了一点约1/50到1/100。
综合非有序或者要求稳定用map,都应该使用unordered_map,set类型也是类似的。
unordered_map 查找效率快五倍,插入更快,节省一定内存。如果没有必要排序的话,尽量使用 hash_map(unordered_map 就是 boost 里面的 hash_map 实现)。

4.使用案例

map:

 1 #include<string>
 2 #include<iostream>
 3 #include<map>
 4
 5 using namespace std;
 6
 7 struct person
 8 {
 9     string name;
10     int age;
11
12     person(string name, int age)
13     {
14         this->name =  name;
15         this->age = age;
16     }
17
18     bool operator < (const person& p) const
19     {
20         return this->age < p.age;
21     }
22 };
23
24 map<person,int> m;
25 int main()
26 {
27     person p1("Tom1",20);
28     person p2("Tom2",22);
29     person p3("Tom3",22);
30     person p4("Tom4",23);
31     person p5("Tom5",24);
32     m.insert(make_pair(p3, 100));
33     m.insert(make_pair(p4, 100));
34     m.insert(make_pair(p5, 100));
35     m.insert(make_pair(p1, 100));
36     m.insert(make_pair(p2, 100));
37
38     for(map<person, int>::iterator iter = m.begin(); iter != m.end(); iter++)
39     {
40         cout<<iter->first.name<<"\t"<<iter->first.age<<endl;
41     }
42
43     return 0;
44 }

输出为:(根据age进行了排序的结果)

Tom1    20
Tom3    22
Tom4    23
Tom5    24
因为Tom2和Tom3的age相同,由我们定义的operator<只是比较的age,所以Tom3覆盖了Tom2,结果中没有Tom2。

如果运算符<的重载是如下

1 bool operator < (const person &p)const{
2     return this->name < p.name;
3 }

输出结果: 按照 那么进行的排序,如果有那么相同则原来的那么会被覆盖

Tom1    20

Tom2    22

Tom3    22

Tom4    23

Tom5    24

参考:http://www.cnblogs.com/NeilZhang/p/5724996.html

http://blog.csdn.net/blues1021/article/details/45054159

时间: 2024-10-11 07:03:14

unordered_map 与 map 的对比(转)的相关文章

(转)unordered_map与map的对比(C++11新特性)

unordered_map和map类似,都是存储的key-value的值,可以通过key快速索引到value.不同的是unordered_map不会根据key的大小进行排序, 存储时是根据key的hash值判断元素是否相同,即unordered_map内部元素是无序的,而map中的元素是按照二叉搜索树存储,进行中序遍历会得到有序遍历. 所以使用时map的key需要定义operator<.而unordered_map需要定义hash_value函数并且重载operator==.但是很多系统内置的数

C++11 新特性: unordered_map 与 map 的对比

unordered_map和map类似,都是存储的key-value的值,可以通过key快速索引到value.不同的是unordered_map不会根据key的大小进行排序, 存储时是根据key的hash值判断元素是否相同,即unordered_map内部元素是无序的,而map中的元素是按照二叉搜索树存储,进行中序遍历会得到有序遍历. 所以使用时map的key需要定义operator<.而unordered_map需要定义hash_value函数并且重载operator==.但是很多系统内置的数

unordered_map和map的区别

unordered_map和map类似,都是存储的key-value的值,可以通过key快速索引到value.不同的是unordered_map不会根据key的大小进行排序, 存储时是根据key的hash值判断元素是否相同,即unordered_map内部元素是无序的,而map中的元素是按照二叉搜索树存储,进行中序遍历会得到有序遍历. 所以使用时map的key需要定义operator<.而unordered_map需要定义hash_value函数并且重载operator==.但是很多系统内置的数

【map】【unordered_map】map和unordered_map中键类型为自定义类型的操作

STL中map的底层为红黑树,所以查找的时间复杂度为O(logn). unordered_map是根据哈希值(遇到哈希值相同时用==号比较)寻找键,所以时间复杂度为O(1). 键类型为自定义类型时,map需要重载键类型的<符号,unordered_map需要定义键类型的哈希函数(在类外定义),以及重载键类型的==符号. class person1 { public: string name; int age; person1(string s,int i):name(s),age(i){} //

Collection与Map的对比

Map:HashMap.HashTable  如何在它们之间选择  一.Array , Arrays  Java所有"存储及随机访问一连串对象"的做法,array是最有效率的一种.  1.  效率高,但容量固定且无法动态改变.  array还有一个缺点是,无法判断其中实际存有多少元素,length只是告诉我们array的容量.  2.Java中有一个Arrays类,专门用来操作array.  arrays中拥有一组static函数,  equals():比较两个array是否相等.ar

c#中泛型集合directory和java中map集合对比

c#中directory的基本用法1.创建及初始化 Dictionary<int, string> myDictionary = new Dictionary<int, string>(); 2.添加元素 myDictionary.Add("C#",0); myDictionary.Add("C++",1); myDictionary.Add("C",2); myDictionary.Add("VB",

c++ map 和 unordered_map的区别

unordered_map和map类似,都是存储的key-value的值,可以通过key快速索引到value.不同的是unordered_map不会根据key的大小进行排序, 存储时是根据key的hash值判断元素是否相同,即unordered_map内部元素是无序的,而map中的元素是按照二叉搜索树存储,进行中序遍历会得到有序遍历. 所以使用时map的key需要定义operator<.而unordered_map需要定义hash_value函数并且重载operator==.但是很多系统内置的数

C++11中新特性之:unordered_map

unordered_map和map类似,都是存储的key-value的值,可以通过key快速索引到value. 不同的是unordered_map不会根据key的大小进行排序,存储时是根据key的hash值判断元素是否相同,即unordered_map内部元素是无序的,而map中的元素是按照二叉搜索树存储,进行中序遍历会得到有序遍历. 所 以使用时map的key需要定义operator<.而unordered_map需要定义hash_value函数并且重载 operator==.但是很多系统内置

STL容器 -- Map

核心描述: map 就是从键(key) 到 值(value) 的一个映射.且键值不可重复,内部按照键值排序. 头文件: #include <map> 拓展: multimap 是一个多重映照容器,键值可以重复.unordered_set 是一个内部不排序的映射容器,需包含头文件<unordered_map> 构造方法: map<int, string> kvm; //构造一个键为 int 型, 值为 string 型的 map 元素的插入: kvm[1] = "