C+中的映射与hash#u映射+; 在C++中,我有一个问题,涉及代码< HASHMAP> 和 MAP>代码>。我知道map在STL中,但hash\u map不是标准。两者之间有什么区别?< P> C++的规范没有确切地告诉你必须使用什么算法来为STL容器使用。但是,它确实对它们的性能施加了某些限制,这就排除了对map和其他关联容器使用哈希表的可能性。(它们最常用红/黑树实现)这些约束要求这些容器具有比哈希表更好的最坏情况性能
然而,许多人确实想要哈希表,因此基于哈希的STL关联容器多年来一直是一种常见的扩展。因此,他们添加了<代码>无序的映射> /COD>以及以后的C++标准版本。 < P>它们以非常不同的方式实现。C+中的映射与hash#u映射+; 在C++中,我有一个问题,涉及代码< HASHMAP> 和 MAP>代码>。我知道map在STL中,但hash\u map不是标准。两者之间有什么区别?< P> C++的规范没有确切地告诉你必须使用什么算法来为STL容器使用。但是,它确实对它们的性能施加了某些限制,这就排除了对map和其他关联容器使用哈希表的可能性。(它们最常用红/黑树实现)这些约束要求这些容器具有比哈希表更好的最坏情况性能,c++,map,hashmap,C++,Map,Hashmap,然而,许多人确实想要哈希表,因此基于哈希的STL关联容器多年来一直是一种常见的扩展。因此,他们添加了无序的映射> /COD>以及以后的C++标准版本。 < P>它们以非常不同的方式实现。 hash_-map(unordered_-map在TR1和Boost中;改用它们)使用一个哈希表,其中键被哈希到表中的一个插槽,值存储在与该键绑定的列表中 map被实现为一个平衡的二叉搜索树(通常是红/黑树) unordered_映射在访问集合的已知元素时应提供稍好的性能,但map将具有其他有用的特性(例如,它
hash_-map
(unordered_-map
在TR1和Boost中;改用它们)使用一个哈希表,其中键被哈希到表中的一个插槽,值存储在与该键绑定的列表中
map
被实现为一个平衡的二叉搜索树(通常是红/黑树)
unordered_映射
在访问集合的已知元素时应提供稍好的性能,但map
将具有其他有用的特性(例如,它以排序顺序存储,允许从头到尾遍历)<代码>无序映射在插入和删除时比映射
更快哈希映射
是许多库实现提供的常见扩展。这就是为什么当它被添加到C++标准中作为Tr1的一部分时,它被重命名为<代码> unordeDeMAP < /C>。map通常是用一个平衡的二叉树来实现的,比如红黑树(实现当然会有所不同)<代码>哈希映射和无序映射
通常通过哈希表实现。因此,秩序无法维持<代码>无序映射插入/删除/查询将是O(1)(恒定时间),其中映射将是O(logn),其中n是数据结构中的项数。因此,unordered_map
速度更快,如果您不关心项目的顺序,则应优先选择map
。有时,您需要维护顺序(按键排序),为此,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
插入和查找操作的时间,因为它实现为一个红黑树数据结构O(log(N))
要求插入和查找的“平均”时间为无序映射
,但允许最坏情况时间为O(1)
。这是因为它是使用哈希表数据结构实现的O(N)
因此,通常,
无序映射会更快,但取决于键和存储的哈希函数,可能会变得更糟。我不知道会有什么结果,但是,哈希映射需要20秒以上的时间才能清除()150K无符号整数键和浮点值。我只是在运行和阅读其他人的代码
这就是它包含哈希映射的方式
#include "StdAfx.h"
#include <hash_map>
#包括“StdAfx.h”
#包括
我在这里读到的
表示clear()是O(N)的顺序。这对我来说很奇怪,但事实就是这样。map
是从平衡二叉搜索树
(通常是rb_树
)实现的,因为平衡二叉搜索树
中的所有成员都是按map>排序的
哈希映射
是从哈希表
实现的。由于哈希表
中的所有成员都未排序,因此哈希映射(无序映射)
中的成员未排序
<代码> HasyMava不是C++标准库,但现在它改名为<代码> unordeDeMalp>/Cuff>(可以考虑重命名),成为C++标准库,因为C++ 11更详细地查看了这个问题。p>
下面我将从源代码中给出一些核心接口,说明如何实现两种类型的映射
地图:
下面的代码只是为了说明,map只是一个平衡二叉搜索树
的包装器,它几乎所有的函数都只是调用平衡二叉搜索树
函数
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);
};
与map的
一样,惟一的成员是rb_树
,hash_映射的
惟一成员是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);
};
};
模板
类哈希映射{
私人:
typedef哈希表ht;
//成员数据是哈希表
ht代表;
公众:
//默认情况下为100个桶
//它可能不是100(在这里只是为了简化)
hash_-map():rep(100){};
//像上面的map的insert函数一样,只需调用rb_树的unique函数
//hash_映射,insert函数只调用hashtable的惟一insert函数
标准::对插入(常量值和v){
返回t.insert_unique(v);
};
};
下图显示了当一个hash_映射有53个bucket并插入一些值时,它的内部结构
下图显示了映射和散列映射(无序映射)之间的一些差异,该图像来自:
它实际上是在TR1中添加的(std::TR1::unordered_map),而不是C++0xI认为map
的原因通常是由于使用operator@kts:任何STL实现是否实际使用B树?从技术上讲,所有二进制搜索树都是B树(1-2树)。话虽如此,我不知道有哪个STL使用红色以外的任何东西/black@bk1e“适当的”B-树在数据库中特别有用,因为您希望“胖”树节点与磁盘页面对齐。OTOH,这在“普通”程序中使用的“平面”内存模型中不是很有用-所有STL