数据结构与算法:2. 哈希表

哈希表也称散列表 hash table。

1.组成:指针(键key),数据(值value)

2.数组的大小一般为质数,因为需要均匀的散布  (求模运算mod,取余数)-》》会有冲突

 3.解决冲突的方式:

①链表式解决:遇到冲突把数据写到next的位置

②开放地址:

一. 基本知识

1. unordered_map基础用法:

1.定义

unordered_map <string值,int键> 哈希表名字;

2. 判断key是否存在

hash.count("abc") != 0 或者 hash.find("abc") != hash.end

3.删除键值对

hashTable.erase("orange")

4.访问

hashTable["apple"]

5. 添加键值对

hashTable["apple"] = 5; hashTable["apple"]++ apple键对应的值加1,结合了索引访问操作符 [] 和后置递增运算符 ++

2.unordered_set 用法

1.创建哈希集合

unordered_set<int> 名字;

2. 添加元素

hashSet.insert(5); // 将元素 5 添加到哈希集合中

3.删除元素

hashSet.erase(5);

4. 判断元素是否存在

if (hashSet.count(10) > 0) { // 元素 10 存在于哈希集合中 }

5. 遍历哈希集合:

for (const auto& element : hashSet) { // 遍历哈希集合中的每个元素 // element 为集合中的一个元素 }

6.获取哈希集合的大小:

int size = hashSet.size(); // 获取哈希集合的元素数量

3. 区别

1.unordered_set 和unordered_map的区别

如果需要存储键值对,并且需要根据键快速访问对应的值,使用 std::unordered_map;如果只需要存储唯一的键并进行快速查找,使用 std::unordered_set

`unordered_set`和`unordered_map`都是用来存储键值对,但是它们的应用场景略有不同:

1. `unordered_set`是一种无序的集合,它只存储唯一的键(没有对应的值)。它的主要应用是判断元素是否存在于集合中,而不关心元素出现的次数。在函数中,使用`unordered_set`来记录每个不同的计数器值,以判断元素出现次数的唯一性。

2. `unordered_map`是一种无序的键值对容器,它存储着键值对的映射关系。它的主要应用是存储需要进行查找、插入和更新的键值对。在函数中,使用`unordered_map`来统计每个元素在数组中出现的次数,其中键表示数组的元素,值表示元素出现的次数。

因此,当你需要进行元素的计数时,使用`unordered_map`更为合适。而当你只关心元素的存在与否,并且不需要计数时,使用`unordered_set`更为合适。

2. count函数和 find 函数区别

都可以用于哈希表的查找操作,但它们的用法和返回值有所不同。

1. `count` 函数:
   - 用法:`hashMap.count(key)`
   - 返回值:
     - 如果找到了键 `key`,返回值为 1;
     - 如果未找到键 `key`,返回值为 0。
   - 适用于判断某个键是否存在于哈希表中。

2. `find` 函数:
   - 用法:`hashMap.find(key)`
   - 返回值:
     - 如果找到了键 `key`,返回一个指向对应键值对的迭代器;
     - 如果未找到键 `key`,返回一个指向哈希表末尾的迭代器(即 `hashMap.end()`)。
   - 适用于查找某个键在哈希表中的位置,并进行相应的操作,如修改值、删除键值对等。

因此,如果只是判断某个键是否存在,可以使用 `count` 函数;如果需要进一步操作或获取键值对的信息,可以使用 `find` 函数,并通过迭代器进行访问。

4.Leetcode题目

1.2215找出两数组的不同 (哈希集合)

因为只是判断元素是否在数组中,所以用unordered_set就行。

//hashtable 之hashset,因为只是看元素是否存在。
// for (int num : vectorname) 这种用法num只是表示vector中的元素,若元素重复num只调用一次
class Solution {
public:
    vector<vector<int>> findDifference(vector<int>& nums1, vector<int>& nums2) {
        unordered_set<int> set1, set2;
        for (int num: nums1){
            set1.insert(num);
        }
        for (int num: nums2){
            set2.insert(num);
        }

        vector<vector<int>> res(2);

        for (int num: set1){
            if (!set2.count(num)){
                res[0].push_back(num);
            }
        }
        for (int num: set2){
            if (!set1.count(num)){
                res[1].push_back(num);
            }
        }
        return res;
        
    }
};

2.1207. 独一无二的出现次数

set和map的区别:要新建一个表单用map,单纯计数用set 

//hashtable
//先用哈希表录入arr中的重复信息,后用set判断表中元素是否重复出现
//键值对 (x, count)
class Solution {
public:
    bool uniqueOccurrences(vector<int>& arr) {
        unordered_map <int,int> mp1;
        unordered_set <int> set1;
        //新建哈希表,表中键是arr每个元素,值是元素出现的次数
       for (const auto& x :arr){
           mp1[x]++;
       }
        //键值对 (x, count)
        //新建哈希集合,再剔除重复的量
       for (const auto& x : mp1){
           set1.insert(x.second);
           
       } 
       return set1.size() == mp1.size();      
    }
};

3. 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
哈希表是一种常用的数据结构,它通过哈希函数将键映射到存储位置,以实现高效的数据查找和插入操作。哈希函数是一种提取数据特征的算法,根据不同的数据形式和场景,可以选择不同的哈希算法。常见的哈希算法包括MD5等。\[1\] 在哈希表中,哈希函数的优劣直接影响到哈希表的查找效率。优秀的哈希函数可以减少冲突的发生,提高查找效率。哈希函数的设计方法有多种,其中常见的包括直接寻址法、除留余数法、平方取中法等。不同的哈希函数适用于不同的数据类型和规律。\[3\] 哈希冲突是指不同的键经过哈希函数计算后得到相同的哈希值,导致数据存储位置冲突的情况。为了解决哈希冲突,常用的方法有开放寻址法和链地址法。开放寻址法是指当发生冲突时,通过一定的规则在哈希表中寻找下一个可用的位置来存储数据。链地址法是指在哈希表的每个位置上维护一个链表,将哈希值相同的键值对存储在同一个链表中。\[2\] 总结来说,哈希表是一种通过哈希函数将键映射到存储位置的数据结构,常用的哈希算法有多种,哈希函数的设计方法也有多种,而哈希冲突的处理方法包括开放寻址法和链地址法。这些算法和数据结构的选择取决于具体的应用场景和需求。 #### 引用[.reference_title] - *1* [详解哈希数据结构,手写哈希表](https://blog.csdn.net/CRMEB/article/details/120820682)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [数据结构哈希表以及常用哈希的算法表达(含全部代码)](https://blog.csdn.net/weixin_53050357/article/details/126666617)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [哈希表-数据结构(C语言)](https://blog.csdn.net/weixin_44681349/article/details/124782035)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值