赞
踩
今日在刷力扣时遇到了哈希表,在以前学习数据结构时粗略学过哈希表,哈希函数,如今在算法题中也是一大应用,下面我根据在网上所学,整理了一下一些有关哈希表的知识,以及如何在C++中使用哈希表。
若关键字为k,则其值存放在f(k)的存储位置上。由此,不需比较便可直接取得所查记录。称这个对应关系f为散列函数,按这个思想建立的表为散列表。
- 直接寻址法:取关键字或关键字的某个线性函数值为散列地址。即H(key)=key或H(key) = a·key + b,其中a和b为常数(这种散列函数叫做自身函数)。若其中H(key)中已经有值了,就往下一个找,直到H(key)中没有值了,就放进去。
- 数字分析法:分析一组数,比如身份证号,等等,找其中的规律构造哈希函数。
- 平方取中法:当无法确定关键字中哪几位分布较均匀时,可以先求出关键字的平方值,然后按需要取平方值的中间几位作为哈希地址。这是因为:平方后中间几位和关键字中每一位都相关,故不同关键字会以较高的概率产生不同的哈希地址。
- 随机数法:选择一随机函数,取关键字的随机值作为散列地址,即H(key)=random(key)其中random为随机函数,通常用于关键字长度不等的场合。
- 除留余数法:取关键字被某个不大于散列表表长m的数p除后所得的余数为散列地址。即 H(key) = key MOD p,p≤m。不仅可以对关键字直接取模,也可在折叠、平方取中等运算之后取模。对p的选择很重要,一般取素数或m,若p选的不好,容易产生同义词。(该方法在408考试中常提及,也是比较熟悉的一种方法
)
- 开放寻址法: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均是不同的散列函数,即在同义词产生地址冲突时计算另一个散列函数地址,直到冲突不再发生,这种方法不易产生“聚集”,但增加了计算时间。
- 链地址法(拉链法)
- 建立一个公共溢出区
下面我将讲述C++中应用hashmap。
unordered_map<string, int> myHashMap;
其中,创建了一个无序哈希表,key和value的值都是int类型,该标的名字为myHashMap。
myHashMap["one"] = 1;
myHashMap["two"] = 2;
myHashMap["three"] = 3;
输入对应的键值对,类似于数组赋值的操作,只不过有2个参数。
std::cout << "Value corresponding to key 'two': " << myHashMap["two"] << std::endl;
类似于数组中下表索引,这里的索引为key值。
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关键字应用于迭代器、模板编程、复杂的类型名字等场景,减少代码冗余。
myHashMap.erase("three");
删除对应key值下的值
std::cout << "All elements in the hash map: ";
for (const auto& pair : myHashMap) {
std::cout << "{" << pair.first << ": " << pair.second << "} ";
}
std::cout << std::endl;
在算法题中,常见的方法就是增删查,所以以上方法已足够应该目前遇到的算法题,后续有新的需要,持续补充这篇博客~
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。