C++哈希表的基本使用


前言

今日在刷力扣时遇到了哈希表,在以前学习数据结构时粗略学过哈希表,哈希函数,如今在算法题中也是一大应用,下面我根据在网上所学,整理了一下一些有关哈希表的知识,以及如何在C++中使用哈希表。

一、哈希表是什么?

  • 散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。
  • 在我的理解下,哈希表就是一个大表格,用来快速查找,一个key对应一个value,由我们得到的key找出value的值。

二、哈希函数

1.定义

若关键字为k,则其值存放在f(k)的存储位置上。由此,不需比较便可直接取得所查记录。称这个对应关系f为散列函数,按这个思想建立的表为散列表。

2.常用方法

  1. 直接寻址法:取关键字或关键字的某个线性函数值为散列地址。即H(key)=key或H(key) = a·key + b,其中a和b为常数(这种散列函数叫做自身函数)。若其中H(key)中已经有值了,就往下一个找,直到H(key)中没有值了,就放进去。
  2. 数字分析法:分析一组数,比如身份证号,等等,找其中的规律构造哈希函数。
  3. 平方取中法:当无法确定关键字中哪几位分布较均匀时,可以先求出关键字的平方值,然后按需要取平方值的中间几位作为哈希地址。这是因为:平方后中间几位和关键字中每一位都相关,故不同关键字会以较高的概率产生不同的哈希地址。
  4. 随机数法:选择一随机函数,取关键字的随机值作为散列地址,即H(key)=random(key)其中random为随机函数,通常用于关键字长度不等的场合。
  5. 除留余数法:取关键字被某个不大于散列表表长m的数p除后所得的余数为散列地址。即 H(key) = key MOD p,p≤m。不仅可以对关键字直接取模,也可在折叠、平方取中等运算之后取模。对p的选择很重要,一般取素数或m,若p选的不好,容易产生同义词。(该方法在408考试中常提及,也是比较熟悉的一种方法

3.处理冲突

  1. 开放寻址法:Hi=(H(key)+ di) MOD
    m,i=1,2,…,k(k≤m-1),其中H(key)为散列函数,m为散列表长,di为增量序列,可有下列三种取法:
    1.1. di=1,2,3,…,m-1,称线性探测再散列;
    1.2. di=12,-12,22,-22,⑶2,…,±(k)2,(km/2)称二次探测再散列;
    1.3. di=伪随机数序列,称伪随机探测再散列。

2.再散列法:Hi=RHi(key),i=1,2,…,k RHi均是不同的散列函数,即在同义词产生地址冲突时计算另一个散列函数地址,直到冲突不再发生,这种方法不易产生“聚集”,但增加了计算时间。

  1. 链地址法(拉链法)
  2. 建立一个公共溢出区

三、C++中使用哈希表

下面我将讲述C++中应用hashmap。

3.1 创建一个哈希表

unordered_map<string, int> myHashMap;

其中,创建了一个无序哈希表,key和value的值都是int类型,该标的名字为myHashMap。

3.2 插入元素

myHashMap["one"] = 1;
myHashMap["two"] = 2;
myHashMap["three"] = 3;

输入对应的键值对,类似于数组赋值的操作,只不过有2个参数。

3.3 访问元素

  std::cout << "Value corresponding to key 'two': " << myHashMap["two"] << std::endl;

类似于数组中下表索引,这里的索引为key值。

3.4检查元素是否存在

    if (myHashMap.find("four") != myHashMap.end()) {
        std::cout << "Value corresponding to key 'four': " << myHashMap["four"] << std::endl;
    } else {
        std::cout << "Key 'four' not found in the hash map." << std::endl;
    }

当你使用 std::unordered_map 时,你可以使用 find 函数来查找哈希表中是否存在某个特定的键。这个函数返回一个迭代器,指向找到的元素,如果元素不存在,则返回指向哈希表末尾的迭代器。
这里的 find 函数实现了一种快速的查找机制,其时间复杂度通常为 O(1),因为哈希表内部是通过哈希函数将键映射到桶(buckets)的,而不是通过线性搜索。具体而言,find 函数会根据传入的键计算其哈希值,然后定位到对应的桶,接着在该桶中进行搜索以找到匹配的元素。如果找到了匹配的元素,则返回指向该元素的迭代器;否则,返回指向哈希表末尾的迭代器。

注:此处find返回一个迭代器,类型是:std::unordered_map<int, int>::iterator,一般在C++中,我们使用auto关键字应用于迭代器、模板编程、复杂的类型名字等场景,减少代码冗余。

3.5 删除元素

 myHashMap.erase("three");

删除对应key值下的值

3.6 打印所有元素

std::cout << "All elements in the hash map: ";
    for (const auto& pair : myHashMap) {
        std::cout << "{" << pair.first << ": " << pair.second << "} ";
    }
std::cout << std::endl;

在算法题中,常见的方法就是增删查,所以以上方法已足够应该目前遇到的算法题,后续有新的需要,持续补充这篇博客~

  • 37
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值