哈希原理实现

server/2024/11/13 5:31:07/

本节主要看源代码实现

哈希特点

哈希(Hashing)是一种将数据映射到固定大小的表中以实现快速查找的数据结构和算法方法。哈希的主要特点包括:

1. 高效的查找、插入和删除

  • 时间复杂度:哈希表通常提供近乎常数时间的查找、插入和删除操作,理想情况下为 ( O(1) )。
  • 性能:由于通过哈希函数直接计算位置,数据可以迅速定位,减少了需要遍历的数据量。

2. 哈希函数

  • 定义:哈希函数是将输入数据(键)映射到哈希表中的一个位置的函数。
  • 特点
    • 确定性:相同的输入始终会映射到相同的位置。
    • 均匀分布:理想的哈希函数将输入数据均匀分布到哈希表的各个槽位,减少冲突的可能性。
    • 快速计算:哈希函数应当能够快速计算,以避免对性能的影响。

3. 冲突处理

  • 冲突:当两个或更多的键被映射到哈希表的同一位置时,称为冲突。
  • 处理方法
    • 链式地址法(Separate Chaining):使用链表或其他数据结构处理同一位置的多个键。
    • 开放地址法(Open Addressing):通过探测策略(如线性探测、二次探测、双重哈希)寻找其他空槽位。

4. 负载因子

  • 定义:负载因子是哈希表中元素数量与表大小的比率。
  • 影响
    • 性能:负载因子较高时,冲突概率增加,操作性能可能下降。
    • 动态调整:通常会在负载因子超过某个阈值时,进行哈希表的扩展和再哈希操作,以保持性能。

开放寻址法

概念:所有元素都存储在哈希表的数组中,冲突发生时,使用探测序列寻找下一个可用位置。

hash节点:

	enum State{EXIST,EMPTY,DELETE};template<class K, class V>struct HashData{pair<K, V> _kv;State _state = EMPTY;};

扩容代码

负载因子保证哈希表永远有剩余空间:负载因子过大则扩容

因子过大,哈希表扩容时,不能只是改变vector.size(会改变映射关系)

应新申请更大size的hashmap,后交换this&newhasnmap

// 扩容if (_n * 10 / _tables.size() >= 7){//vector<HashData<K, V>> newTables(_tables.size() * 2);遍历旧表, 将所有数据映射到新表...//_tables.swap(newTables);HashTable<K, V, Hash> newHT;newHT._tables.resize(_tables.size() * 2);for (size_t i = 0; i < _tables.size(); i++){if (_tables[i]._state == EXIST){newHT.Insert(_tables[i]._kv);  //方法复用, 自动正确插入}}_tables.swap(newHT._tables);   //nb swap}

key不是int:先将key映射成int

自定义仿函数
struct StringHashFunc{size_t operator()(const string& s){size_t hash = 0;for (auto e : s){hash *= 31;hash += e;}return hash;}};
特化模板

(可默认调用, 省去传递仿函数类)

template<class K>
struct HashFunc
{size_t operator()(const K& key){return (size_t)key;}
};// 特化
template<>
struct HashFunc<string>
{size_t operator()(const string& key){size_t hash = 0;for (auto e : key){hash *= 31;hash += e;}return hash;}
};

对应默认调用

//当k为string时, Hash默认为特化后的类
template<class K, class V, class Hash = HashFunc<K>>class HashTable{public:HashTable(){_tables.resize(10);}....}

 

拉链法:(哈希桶)

库里方法就是哈希桶实现哈希表

每个vector节点存一个链表头结点

单向链表,插入方便(头插)

再优化的话,可把节点换为map地址,防止一条链表过长影响效率

扩容时直接插入原节点,防重复删除又申请相同节点

扩容代码

// 负载因子==1扩容if (_n == _tables.size()){//重复delete & new, 不如直接转移/*HashTable<K, V> newHT;newHT._tables.resize(_tables.size() * 2);for (size_t i = 0; i < _tables.size(); i++){Node* cur = _tables[i];while(cur){newHT.Insert(cur->_kv);cur = cur->_next;}}_tables.swap(newHT._tables);*/// 推荐写法:将原有各节点转移到new的hashmap, 省去了delete&newvector<Node*> newtables(_tables.size() * 2, nullptr);for (size_t i = 0; i < _tables.size(); i++){Node* cur = _tables[i];while (cur){Node* next = cur->_next;// 旧表中节点,挪动新表重新映射的位置size_t hashi = hs(cur->_kv.first) % newtables.size();// 头插到新表cur->_next = newtables[hashi];newtables[hashi] = cur;cur = next;}_tables[i] = nullptr;}_tables.swap(newtables);}

类模板特化

template<class K>
struct HashFunc
{size_t operator()(const K& key){return (size_t)key;}
};// 特化
template<>
struct HashFunc<string>
{size_t operator()(const string& key){size_t hash = 0;for (auto e : key){hash *= 31;hash += e;}return hash;}
};
更多模板特化信息:

http://t.csdnimg.cn/IEY8T

板书


http://www.ppmy.cn/server/103703.html

相关文章

中国植物性状数据库

中国植物性状的研究主要集中在植物的生理结构和功能&#xff0c;‌以及它们对环境的适应性上。‌中国植物性状的多样性体现在多个方面&#xff0c;‌包括植物的生理结构、‌生长习性、‌以及对环境的适应性等。 中国植物性状数据库&#xff0c;包含了来自140个样点的1529种植物…

Educational Codeforces Round 169 (Rated for Div. 2) ABCD+E补

A题&#xff1a;Closest Point 题意 给定若干不同的点&#xff0c;问是否存在一个与这些点不同的点&#xff0c;使得其是对于它们之中的每一点最近 思路 A题不会有很大的难度&#xff0c;我们正常想&#xff0c;如果出现三个点的话&#xff0c;就无法再添加点使得它是全体最…

djnago之序列化器的用法

Django 的序列化器&#xff08;Serializers&#xff09;是 Django REST framework&#xff08;DRF&#xff09;中的一个核心组件&#xff0c;用于将复杂的数据类型&#xff08;如 Django 模型实例&#xff09;转换为 JSON、XML 或其他内容类型&#xff0c;反之亦然。序列化器不…

Android MVVM框架详解与应用

在Android开发中&#xff0c;随着应用复杂度的增加&#xff0c;如何有效地组织和管理代码成为了一个重要的问题。MVVM&#xff08;Model-View-ViewModel&#xff09;架构模式因其清晰的结构和高效的开发效率&#xff0c;逐渐成为Android开发者们青睐的架构模式之一。本文将详细…

Flink程序部署与提交

前言 我们看门见山,生产环境一般用的是在YARN上面采用应用模式进行部署flink程序。实际生产中一般需要和资源管理平台(如YARN)结合起来,选择特定的模式来分配资源、部署应用。 部署模式 在一些应用场景中,对于集群资源分配和占用的方式,可能会有特定的需求。Flink 为各…

英语中apartment(公寓)(美式)、house(房子)、flat(公寓)(英式)、villa(别墅)、room(房间)区别

文章目录 英语中apartment、house、flat、villa、room区别 英语中apartment、house、flat、villa、room区别 在英语中&#xff0c;“apartment”、“house”、“flat”、“villa”、和 “room” 这些词语都与居住空间有关&#xff0c;但它们各自的含义和用途有所不同&#xff…

代码随想录算法训练营第四十六天 | 动态规划 part13

647. 回文子串 class Solution { public:int countSubstrings(string s) {vector<vector<bool>> dp(s.size(), vector<bool>(s.size(), false));int result 0;for (int i s.size() - 1; i > 0; i--) {for (int j i; j < s.size(); j) {if (s[i] s…

打卡学习Python爬虫第三天|python的re模块的使用

如何在python程序中使用正则表达式&#xff1f;就是使用re模块 re模块使用&#xff1a; 1、findall查找所有&#xff0c;返回list list re.findall("n","I love learning English and Chinese!") print(list) # 输出结果&#xff1a;[n,n,n,n,n] list…