Answers:
它们以非常不同的方式实现。
hash_map
(unordered_map
在TR1和Boost中;请改用它们)使用哈希表,其中密钥被哈希到表中的插槽,并且值存储在与该密钥绑定的列表中。
map
被实现为平衡的二进制搜索树(通常是红色/黑色树)。
可以unordered_map
为访问集合中的已知元素提供更好的性能,但是map
可以具有其他有用的特性(例如,它以排序顺序存储,这允许从头到尾遍历)。 unordered_map
在插入和删除时比更快map
。
hash_map
是许多库实现提供的通用扩展。这就是将它重命名为unordered_map
TR1的一部分时将其重命名为C ++标准的原因。映射通常是通过平衡的二叉树(如红黑树)来实现的(实现方式当然会有所不同)。 hash_map
并且unordered_map
通常使用哈希表实现。因此,不维持顺序。 unordered_map
插入/删除/查询将为O(1)(恒定时间),其中映射将为O(log n),其中n是数据结构中的项目数。因此unordered_map
速度更快,如果您不在乎项目的顺序,则应该优先选择map
。有时您想要保持顺序(按键排序),map
因此可以选择。
C ++规范没有确切说明必须为STL容器使用哪种算法。但是,它确实对它们的性能施加了某些限制,从而排除了对哈希表map
和其他关联容器的使用。(它们通常用红色/黑色树来实现。)与散列表相比,这些约束要求这些容器具有更好的最坏情况性能。
但是,确实有很多人想要哈希表,因此多年来,基于哈希的STL关联容器一直是常见的扩展。因此,他们unordered_map
在C ++标准的更高版本中添加了。
map
通常是btree平衡,这是由于使用operator<()
它来确定位置。
map
从balanced binary search tree
(通常是a rb_tree
)实现,因为in中的所有成员balanced binary search tree
都按map排序;
hash_map
从中实现hashtable
。由于in中的所有成员都未排序,hashtable
因此in中的成员hash_map(unordered_map)
未排序。
hash_map
不是c ++标准库,但现在将其重命名为unordered_map
(您可以认为它已重命名)并成为c ++标准库,因为c ++ 11看到此问题hash_map和unordered_map之间的区别?有关更多详细信息。
下面,我将从源代码中提供一些核心接口,说明如何实现两种类型的映射。
下面的代码只是为了说明,map只是一个的包装balanced binary search tree
,几乎所有的功能都只是调用该balanced binary search tree
功能。
template <typename Key, typename Value, class Compare = std::less<Key>>
class map{
// used for rb_tree to sort
typedef Key key_type;
// rb_tree node value
typedef std::pair<key_type, value_type> value_type;
typedef Compare key_compare;
// as to map, Key is used for sort, Value used for store value
typedef rb_tree<key_type, value_type, key_compare> rep_type;
// the only member value of map (it's rb_tree)
rep_type t;
};
// one construct function
template<typename InputIterator>
map(InputIterator first, InputIterator last):t(Compare()){
// use rb_tree to insert value(just insert unique value)
t.insert_unique(first, last);
}
// insert function, just use tb_tree insert_unique function
//and only insert unique value
//rb_tree insertion time is : log(n)+rebalance
// so map's insertion time is also : log(n)+rebalance
typedef typename rep_type::const_iterator iterator;
std::pair<iterator, bool> insert(const value_type& v){
return t.insert_unique(v);
};
hash_map
:hash_map
从其hashtable
结构有点像这样实现:
在下面的代码中,我将给出的主要部分hashtable
,然后给出hash_map
。
// used for node list
template<typename T>
struct __hashtable_node{
T val;
__hashtable_node* next;
};
template<typename Key, typename Value, typename HashFun>
class hashtable{
public:
typedef size_t size_type;
typedef HashFun hasher;
typedef Value value_type;
typedef Key key_type;
public:
typedef __hashtable_node<value_type> node;
// member data is buckets array(node* array)
std::vector<node*> buckets;
size_type num_elements;
public:
// insert only unique value
std::pair<iterator, bool> insert_unique(const value_type& obj);
};
就像map's
唯一成员一样rb_tree
,hash_map's
唯一成员也是hashtable
。它的主要代码如下:
template<typename Key, typename Value, class HashFun = std::hash<Key>>
class hash_map{
private:
typedef hashtable<Key, Value, HashFun> ht;
// member data is hash_table
ht rep;
public:
// 100 buckets by default
// it may not be 100(in this just for simplify)
hash_map():rep(100){};
// like the above map's insert function just invoke rb_tree unique function
// hash_map, insert function just invoke hashtable's unique insert function
std::pair<iterator, bool> insert(const Value& v){
return t.insert_unique(v);
};
};
下图显示了hash_map具有53个存储桶并插入一些值时,它是内部结构。
下图显示了map和hash_map(unordered_map)之间的一些区别,该图像来自于如何在map和unordered_map之间进行选择?:
我不知道是什么,但是,hash_map需要20多秒钟才能清除()150K无符号整数键和浮点值。我只是在运行并阅读别人的代码。
这就是它包含hash_map的方式。
#include "StdAfx.h"
#include <hash_map>
我在这里https://bytes.com/topic/c/answers/570079-perfomance-clear-vs-swap阅读
说clear()是O(N)的顺序。这对我来说很奇怪,但是事实就是这样。