哈希表的定义和查找方法就不再赘述,此随笔主要写代码中的用法加深自己印象。

声明哈希表:

#include<unordered_map>
unordered_map<eleType_1, eleType_2> var_name;
unordered_map<int, int> map;
//或者之前用过的char int类型,char为key,int为char的值。后面的变量为两个
unordered_map<char, int> ans, arr; 

初始化哈希表

//这是int型的
unordered_map<int,int> hmap{ {1,10},{2,15},{3,20},{4,0},{5,12}}; 
//这是以char为关键字
unordered_map<char, int> ans{ {a,1},{b,1},{c,1},{f,2}}; 

通过直接赋值来进行元素添加(类似数组)

//这里是把hamp的key对应的数值进行改变,例如
//把上面的{4,0}中的值改成了14,{5,12}中的值改成15
hmap[4] = 14;
hmap[5] = 15;

同时还有内置函数insert来实现元素插入

hamp.insert({5,15});

复制另一个不为空的哈希表,把hmap复制给tests

unordered_map<int,int>hmap{ {1,10},{2,8},{3,7}};
unordered_map<int,int> tests(hmap);

STL中的常用函数

//申请迭代器,把迭代器的位置赋值到哈希表起始位置
unordered_map<int,int>::iterator iter = hmap.begin();
cout << iter->first << ":" <<iter->second;
//下面等同于上面
unordered_map<char,int> ans;
unordered_map<char,int>::iterator iter = ans.begin()
unordered_map<char,int>::iterator tailer = ans.end()

1)begin函数,类似于return head,返回开始位置的迭代器,iterator是迭代器的类型
2)end函数,就是在哈希表的结尾位置的下一个元素的迭代器
如下copy-paste 解释
在 C++ 标准库的 unordered_map 中,.end() 返回的是一个指向容器末尾位置之后一个位置的迭代器。也就是说,tailer 指向的位置并不是容器中最后一个元素,而是超出容器实际元素范围的一个位置。这个位置通常被称为“哨兵”或“尾后迭代器”。
这意味着 tailer 不能用于访问任何有效的元素,如果试图解引用它(例如 *tailer),会导致未定义行为。因此,通常在迭代遍历容器时,用 iter != ans.end() 作为循环结束的条件,而不会试图访问 end() 所指向的位置。

int main() {
    std::unordered_map<char, int> ans;
    ans['a'] = 1;
    ans['b'] = 2;
    ans['c'] = 3;
    // 申请迭代器并初始化为哈希表的末尾位置
    std::unordered_map<char, int>::iterator tailer = ans.end();
    // 遍历哈希表
    for (std::unordered_map<char, int>::iterator iter = ans.begin(); iter != ans.end(); ++iter) {
        std::cout << iter->first << ": " << iter->second << std::endl;
    }
    return 0;

3)cbegin和cend 这两个函数与begin|end的用法相同,只不过是"const"->即无法改变的“常”哈希表

const unordered_map<int,int> hmap{{1,10},{2,12},{3,12}};
unordered_map<int,int>::const_iterator iter_b = hmap.cbegin();
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~iter_a = hmap.cend();

4)删除元素,hamp.erease()和clear()。

myMap.erase(1) //删除键为1的元素
myMap.clear() //清空整个哈希表
-----------------------------------------------------
    std::unordered_map<int, std::string> myMap;
    myMap[1] = "one";
    myMap[2] = "two";
    myMap[3] = "three";
    myMap.erase(1);
/*哈希表中剩余元素有
2: two
3: three
*/

如果要删除所有值为特定值的元素,需要遍历整个哈希表

    std::unordered_map<int, int> myMap;
    myMap[1] = 10;
    myMap[2] = 20;
    myMap[3] = 10;
    myMap[4] = 30;
    // 遍历哈希表删除值为10的元素
    for (auto it = myMap.begin(); it != myMap.end(); ) {
        if (it->second == 10) {
            it = myMap.erase(it);  // erase 返回下一个元素的迭代器
        } else {
            ++it;
        }
    }
    // 遍历哈希表查看剩余元素
    for (const auto &pair : myMap) {
        std::cout << pair.first << ": " << pair.second << std::endl;
    }

这段代码中输出就是2:20 4:30,所有值为10的元素都被删除了。

上面大多用map来举例,C++中常用的还有unordered_set,unordered_set和unordered_map有一定区别,但都是基于哈希表实现的容器。其中:

  1. 数据存储类型:
  • unordered_set:存储唯一的元素,没有重复值。它是一个集合,每个元素只能出现一次。
  • unordered_map:存储键值对(key-value pairs),其中键是唯一的,但值可以重复。它是一个映射容器,每个键只能出现一次。之前我们举例都是基于此类型{1,10},{2,20}...
  1. 访问方式:
  • unordered_set:只能通过元素值来访问,不支持通过索引访问。
  • unordered_map:可以通过键来访问对应的值,类似于字典映射等。
  1. 插入操作:
  • unordered_set:只能插入值,插入操作返回一个pair,第一个元素是一个迭代器,指向插入位置,第二个元素十一个bool 代表插入是否成功。
  • unordered_map:插入是键值对,插入操作也返回一个pair,同set