C++ hash table and stuff

C++ hash table and related stuff

1. 引入

主要涉及的模板类有set/unordered_set/map/unordered_map。其中,无unordered前缀的版本(即set和map)均内部实现红黑树,而unordered_set和unordered_map内部实现哈希表。此外,map组与set组之间区别在于内部数据形式,set组均为单一数据,而map组则为std::pair格式的键值对,先key,再value。

插入部分:std::pair的简单用法

  • 主成员变量first和second是成员变量,不是成员函数,不用加括号
  • 构造语句写法和vector完全一样,可以有如下方式:
std::pair<int, int> ppp = {1, 2};  
std::pair<int, int> ppp(1, 2);  
std::pair<int, int> ppp{1, 2};  
  • 使用make_pair构造右值pair时,无需传入模板类型,即直接uMap.insert(make_pair(1, "str"))即可。
  • 当然使用正常的右值pair构造时就需要传入模板类型,如uMap.insert(pair<int, bool>(1, true));

2. 红黑树与哈希表容器的简单对比

红黑树map/set:

  • 优点:
    • 有序性,最大的优点,其元素的有序性在很多应用中都会简化很多的操作
    • 高效且稳定,查询、插入操作时间复杂度稳定为O(logN)
  • 缺点:
    • 空间占用率高,以红黑树作为内部实现时,每一个节点都需要额外保存父节点、孩子节点和红/黑性质等数据字段,使得每一个节点都占用大量的空间
    • 查找的平均时间不如哈希表
  • 适用处: 对数据排序有顺序要求的场景

哈希表 unordered_map/unordered_set:

  • 优点:
    • 效率极高,查询和插入的平均时间复杂度为O(1)
  • 缺点:
    • 无序性
    • 哈希表的建立比较耗时
    • 在部分情况下,性能不稳定。比如当大量插入数据时,可能触发大量rehash;当哈希函数设置不合理时,冲突过多,单次查询/插入操作最坏时间复杂度达到O(N)
  • 适用处: 高效率的查找场景

对比小结:

在需要元素有序性或者对单次查询性能要求较为敏感时,请使用map/set,其余情况下应使用unordered_map/unorderer_set。

刷题踩的坑

哈希表好归好,但是需要格外注意其无序性。若需要用到哈希表将一个数组进行散列化,由于哈希表内部的无序,往往需要用unordered_map保存元素的原始数组下标。即:键值对中,key为nums[i],value为i。

3. 常用成员函数

  • insert 插入数据。返回值是一个pair,其second值是一个bool变量,代表插入是否冲突
  • find 查询数据。返回值是iterator,如果查找失败,则返回值等于end();此外也可以用count查询数据,查询成功为1,否则为0
  • 修改数据的时候,可以用iterator或者operator[],如下所示:
unordered_map<int, int> uMap;
uMap.insert(pair<int, int>(1, 1));
uMap.insert(make_pair(2, 2));

auto iter = uMap.find(2);
++(*iter).second;
cout << uMap[2] << endl;
++uMap[2];
cout << uMap[2] << endl;

但是需要注意,operator[]在键值不存在的时候会直接进行数据的插入,然后再返回其映射值的引用。当你不确定某键值是否存在于哈希表中,请使用find而非operator[]。

  • erase删除数据。参数可以是键值,可以是一个迭代器,可以是两个迭代器[left, right]。
uMap.erase(1);
uMap.erase(iter);
uMap.erase(uMap.begin(), uMap.end());

4. 一些比较有启发的用法

LeetCode-17 电话号码的字母组合

unordered_map<char, string> table{
        {'0', " "}, {'1',"*"}, {'2', "abc"},
        {'3',"def"}, {'4',"ghi"}, {'5',"jkl"},
        {'6',"mno"}, {'7',"pqrs"},{'8',"tuv"},
        {'9',"wxyz"}};  

5. 参考

https://www.cnblogs.com/yimeixiaobai1314/p/14375195.html

知识共享许可协议
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇