欢迎光临
我们一直在努力

哈希表unordered_map

哈希表unordered_map

  • 前言
  • 哈希表
  • unordered_map
    • 基础unordered_map
    • 为什么叫 unordered
    • 遍历
    • 查找与删除
  • 问题呈现
    • 1.如果有好几个元素都在6桶,那他又是如何找到我需要的那个元素的
    • 2.为什么无序的底层逻辑

前言

在学习unordered_map之前,我们最好将哈希表回顾一遍,对哈希表的底层运行深入了解,有利于我们接触unordered_map。 对于哈希表和unordered_map,经过学习后也提出了一些问题,放在结尾,各位也可以看看自己是否有同样的问题。

哈希表

如果现在有100万个对象,而你需要从中找到一个叫王五的人,难道需要从头到尾遍历吗。 由此引申出了哈希表。 哈希函数 他会给每一个成员赋予一个数字,而数字有大有小。 存入:王五 -> 100 哈希函数算出:王五 -> 123456 然后 123456 % 10 于是存到桶6 而桶6就是寻找王五的靶子。

0
1
2
3
4
5
6 -> 王五
7
8
9

这种查找方式会直接将目标瞄准桶6,因而省去遍历。 所以查找速度接近O(1)

unordered_map

基础unordered_map

unordered_map是以键值对(Key-Value)的形式进行存储的,如果与上面的哈希表相连,我们就可以清楚地发现王五便是其中的key可以通过key去找寻相应的value。 可以这样理解。

王五

哈希函数

6

找到(王五,95)

返回95

这也就引出了最简单的使用代码

#include <iostream>
#include <unordered_map>
using namespace std;

int main()
{
unordered_map<string, int> age;

age["张三"] = 18;
age["李四"] = 20;

cout << age["张三"] << endl;
return 0;
}

为什么叫 unordered

如下代码

unordered_map<string, int> age;

age["A"] = 1;
age["B"] = 2;
age["C"] = 3;

for(auto p : age)
{
cout << p.first << " "
<< p.second << endl;
}

输出顺序如何A B C? 实际上不一定。 可能:

C 3
A 1
B 2

也可能:

B 2
C 3
A 1

遍历

直接使用lambda形式遍历即可

for(auto p : age)
{
cout << p.first
<< " : "
<< p.second
<< endl;
}

其中p.first是 key p.second是 value

查找与删除

对于查找 一定要先用find确认是否存在 如果直接cout << age[“赵六”]; 如果赵六不存在,会自动创建:赵六 -> 0

auto it = age.find("张三");

if(it != age.end())
{
cout << it->second;
}

删除直接age.erase(“张三”);即可

问题呈现

1.如果有好几个元素都在6桶,那他又是如何找到我需要的那个元素的

对于这种情况

6

王五 -> 100

张三 -> 90

李四 -> 80

计算机会通过哈希函数直接定位到桶6,而不是从桶0开始找,也不是遍历整个哈希表 桶6里面有: 王五 张三 李四 这时才需要比较: 王五 ❌ 张三 ✅

2.为什么无序的底层逻辑

假设有 10 个桶:

0
1
2
3
4
5
6
7
8
9

插入:

age["A"] = 1;
age["B"] = 2;
age["C"] = 3;

它会先计算哈希值。

例如

A -> 哈希值100
B -> 哈希值56
C -> 哈希值123

然后:

100 % 10 = 0
56 % 10 = 6
123 % 10 = 3

整个哈希表就类似于这种情况

0 : A
1 :
2 :
3 : C
4 :
5 :
6 : B
7 :
8 :
9 :

从桶0开始遍历,自然输出ABC 但哈希值是随机的,这就导致了ABC这三个字母,出现了很多排列方法,自然是无序的。

赞(0)
未经允许不得转载:171主机测评 » 哈希表unordered_map
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址