map与unordered_map

来源:互联网 发布:淘宝怎样退货退款申请 编辑:程序博客网 时间:2024/06/07 06:06

一、简介

  随着C++ 0x标准的确立,C++的标准库中也终于有了hashtable。很久以来,STL中都只提供 <map>作为存放对应关系的容器,内部通常用红黑树实现,原因是二叉平衡树(如红黑树)的各种操作,插入、删除、查找等,都是稳定的时间复杂度,即O(logn);但是对于hash表来说,由于无法避免re-hash所带来的性能问题,即使大多数情况下hash表的性能非常好,但是re-hash所带来的不稳定性在当时是不能容忍的。

  不过由于hash表的性能优势,它的使用面还是很广的,于是第三方的类库基本都提供了支持,比如MSVC中的 <hash_map>,Boost中的 <boost/unordered_map.hpp>。后来Boost的unordered_map被吸纳进了TR1(C++ Technical Report1),然后在C++ 0x中被最终定了标准。

二、map

1.std::map

// <map>template < class Key,    class T,    class Compare = less<Key>,    class Alloc = allocator<pair<const Key,T> >> class map;

映射表(Map)容器是一个按特定顺序存储以键值对组合而成的元素的关联容器(Associative container)。

容器特性:

  • 关联(Associative)关联容器中的元素是通过主键(Key)而不是它们在容器中的绝对位置来引用的。
  • 有序(Ordered)容器中的元素在任意时刻都遵循一个严格排序规则。所有插入的元素都按该排序规则获得对应的位置。
  • 映射(Map)每个元素为一个值(Mapped value)绑定一个键(Key):以主键来标志主要内容等于被映射值的元素。
  • 键唯一(Unique keys)容器中不存在两个元素有相同的主键。
  • 能够感知内存分配器的(Allocator-aware)容器使用一个内存分配器对象来动态地处理它的存储需求。

2.模版参数

(1)Key 主键的类型。

  在类模板内部,使用其别名为 key_type 的成员类型。

(2)T 被映射的值的类型。

  在类模板内部,使用其别名为 mapped_type 的成员类型。

(3)Compare 一个二元谓词,以两个元素的主键为参数返回一个 bool 值。

  可以是函数指针(Function pointer)类型或函数对象(Function object)类型。

在类模板内部,使用其别名为 key_compare 的成员类型。

(4)Alloc 容器内部用来管理内存分配及释放的内存分配器的类型。

  这个参数是可选的,它的默认值是std::allocator,这个是一个最简单的非值依赖的(Value-independent)内存分配器。在类模板内部,使用其别名为 allocator_type 的成员类型。

3.详细说明

  在一个映射表容器中,主键通常被用来排序及唯一标志一个元素,而被映射的值保存了与该主键关联的内容。主键与被映射值的类型可以不同,在模板内部,这两种类型合并绑定成成员类型 value_type。由上述描述可知,value_type 是一个双元组类型(Pair type),具体定义如下:

typedef pair<const Key, T> value_type;

(1)map 容器中的所有元素都是按由类型为 Compare 的比较对象指定的严格弱序规则排序的。

  在用主键访问单个元素时,map 容器通常比 unordered_map 容器低效,但 map 容器允许按顺序直接对某个子集进行迭代。

(2)map 容器通常被实现为一个二叉搜索树(及其变型),该数据结构具有对数据自动排序的功能。

  在所有关联容器中,map 容器唯一具有的一个特点:实现了直接访问操作符(operator[]),使得可以直接访问被映射的值。

(3)map 容器支持双向迭代。

三、unordered_map

1.std::unordered_map

C++11

// <unordered_map>template < class Key,    class T,    class Hash = hash<Key>,    class Pred = equal_to<Key>,    class Alloc = allocator< pair<const Key,T> >> class unordered_map;

无序映射表(Unordered Map)容器是一个存储以键值对组合而成的元素的关联容器(Associative container),容器中的元素无特别的次序关系。该容器允许基于主键地快速检索各个元素。

容器特性:

  • 关联(Associative)关联容器中的元素是通过主键(Key)而不是它们在容器中的绝对位置来引用的。
  • 无序(Unordered)无序容器通过 hash 表来组织它们的元素,允许通过主键快速地访问元素。
  • 映射(Map)每个元素为一个值(Mapped value)绑定一个键(Key):以主键来标志主要内容等于被映射值的元素。
  • 键唯一(Unique keys)容器中不存在两个元素有相同的主键。
  • 能够感知内存分配器的(Allocator-aware)容器使用一个内存分配器对象来动态地处理它的存储需求。

2.模版参数

(1)Key 主键的类型。

  在类模板内部,使用其别名为 key_type 的成员类型。

(2)T 被映射的值的类型。

  在类模板内部,使用其别名为 mapped_type 的成员类型。

(3)Hash 一元谓词,以一个 Key 类型的对象为参数,返回一个基于该对象的 size_t 类型的唯一值。

  可以是函数指针(Function pointer)类型或函数对象(Function object)类型。在类模板内部,使用其别名为 hasher 的成员类型。

(4)Pred 二元谓词,以两个 Key 类型的对象为参数,返回一个 bool 值,如果第一个参数等价于第二个参数,该 bool 值为 true,否则为 false。默认为 std::equal_to。

  可以是函数指针类型(Function pointer)类型或函数对象(Function object)类型。
在类模板内部,使用其别名为 key_equal 的成员类型。

(5)Alloc 容器内部用来管理内存分配及释放的内存分配器的类型。

  这个参数是可选的,它的默认值是std::allocator,这个是一个最简单的非值依赖的(Value-independent)内存分配器。在类模板内部,使用其别名为 allocator_type 的成员类型。

3.详细说明

  在一个 unordered_map 容器中,主键通常被用来唯一标志(Uniquely identify)一个元素,而被映射的值保存了与该主键关联的内容。主键与被映射值的类型可以不同,在模板内部,这两种类型合并绑定成成员类型 value_type。由上述描述可知,value_type 是一个双元组类型(Pair type),具体定义如下:

typedef pair<const Key, T> value_type;

(1)在 unordered_map 内部,元素不会按任何顺序排序,而是通过主键的hash值将元素分组放置到各个槽(Bucket,也可译成“桶”)中,这样就能通过主键快速地访问各个对应的元素(平均耗时为一个常量,即时间复杂度为 O(1))。

(2)在访问容器中的某个元素时,unordered_map容器比map容器高效,而在迭代容器元素的某个子集时,前者比后者稍微低效了一点。

(3)unordered_map 实现了直接访问操作符(operator[]),使得可以通过主键(Key value)直接访问被映射的值(Mapped value)。

(4)unordered_map 容器支持正向迭代。

四、总结

  在 unordered_map内部,元素不会按任何顺序排序,而map容器中的所有元素都是按由类型为Compare的比较对象指定的严格弱序规则排序的;在访问容器中的某个元素时,unordered_map容器比map容器高效。

五、参考目录

C++参考手册

std::map

std::unordered_map

0 0
原创粉丝点击