Chinaunix首页 | 论坛 | 博客
  • 博客访问: 32215
  • 博文数量: 11
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 100
  • 用 户 组: 普通用户
  • 注册时间: 2014-10-19 21:19
文章分类
文章存档

2015年(2)

2014年(9)

我的朋友

分类: C/C++

2015-08-12 17:36:07

map的实现是红黑树,遍历使用中序遍历,由于是二叉搜索树,所以是有序的;
unordered_map的实现是hash_table;
hash_map在unordered_map实现之前先实现,但是unordered_map作为STL的标准被加入;hash_map和c++ stl的api不兼容,c++ tr1(C++ Technical Report1)作为标准的扩展,实现了hash map,提供了和stl兼容一致的api,称为unorder_map.在头文件 <tr1/unordered_map>中。
使用unordered_map,尽量不使用hash_map。

如果仅仅使用get操作,不涉及排序,使用unordered_map更优,因为get操作的时间复杂度为O(1),而map的时间复杂度是lg(N);
例如3Sum需要插入排序,所以使用map。

使用自定义类型作为Key
map由于是红黑树,同时也是二叉搜索树,所以需要自定义类型需要重载'<'操作符。

使用unordered_map就比较复杂一点:
类需要重载==,用于如果hash值相同时,判断两个实体是否相同;
所以这个就会导致insert的最坏情况是O(N),insert的平均时间是O(1);思考:最坏是O(N),hash冲突采用的是开链法,最坏的时间是O(N);
map的insert的时间复杂度是lg(N);

另外自定义类的hash值怎么计算,所以需要另外一个计算自定义类的hash函数。例子如下:
	
	
  1. struct Key
  2. {
  3.   std::string first;
  4.   std::string second;
  5.   int third;
  6.   bool operator==(const Key &other) const
  7.   { return (first == other.first
  8.             && second == other.second
  9.             && third == other.third);
  10.   }
  11. };
  12. struct KeyHasher
  13. {
  14.   std::size_t operator()(const Key& k) const
  15.   {
  16.     using std::size_t;
  17.     using std::hash;
  18.     using std::string;
  19.     return ((hash<string>()(k.first)
  20.              ^ (hash<string>()(k.second) << 1)) >> 1)
  21.              ^ (hash<int>()(k.third) << 1);
  22.   }
  23. };
  24. int main()
  25. {
  26.   std::unordered_map<Key,std::string,KeyHasher> m6 = {
  27.     { {"John", "Doe", 12}, "example"},
  28.     { {"Mary", "Sue", 21}, "another"}
  29.   };
  30. }
阅读(3985) | 评论(0) | 转发(0) |
0

上一篇:C++ 构造析构函数总结

下一篇:没有了

给主人留下些什么吧!~~