当前位置: 首页 > wzjs >正文

六安网站建设哪家靠谱武汉seo顾问

六安网站建设哪家靠谱,武汉seo顾问,网站 banner 尺寸,上传了网站标志怎么弄注意:本篇文章内容我们了解即可,后续对unordered_set和unorder_map的封装是基于哈希桶实 现的! 首先,为了理解开放寻址法,我们要从哈希的概念入手,哈希简单来说就是对一堆数,通过某…

注意:本篇文章内容我们了解即可,后续对unordered_set和unorder_map的封装是基于哈希桶实             现的!

首先,为了理解开放寻址法,我们要从哈希的概念入手,哈希简单来说就是对一堆数,通过某种特定的方式(即哈希函数)将其映射出来,但是有可能两个数会被映射到同一位置上,这便产生了冲突,我们成为哈希冲突,为了解决这一冲突,我们可以采用开放寻址法来解决问题!

1. 基本原理

开放寻址法的核心思想是:当发生冲突时,按照某种探测序列在哈希表中寻找下一个空的槽位来存储冲突的键值对。探测序列可以是线性的、二次的或基于另一个哈希函数的。说人话就是这个位置有人了,我去下一个位置蹲着去,不管后进来的人,后面的人来了发现自己的坑被占了,在去占别人的位置,这是一种不文明的行为,大家不要学哈

2. 探测方法

  • 线性探测(Linear Probing):当发生冲突时,依次检查后续的槽位,直到找到一个空槽。

  • 二次探测(Quadratic Probing):当发生冲突时,按照二次函数的步长来探测后续槽位。

  • 双重哈希(Double Hashing):第一个哈希函数计算出的值发生冲突,使用第二个哈希函数                                                       计算出一个跟key相关的偏移量值,不断往后探测,直到寻                                                         找到下一个没有存储数据的位置为止。

3. 操作步骤

1)框架构造

我们的哈希表可以采用vector结构,这样方便我们寻址,我们还需要设置一个参数用来检验我们的哈希表的饱满程度,还需要设置一个状态位,以及哈希节点。其他的一些基本结构和前面的哈希桶是一样的!

参考代码:

//哈希的线性探测
#pragma once
#include<string>
#include<vector>
#include<utility>
#include<iostream>
using namespace std;static const int __stl_num_primes = 28;
static const unsigned long __stl_prime_list[__stl_num_primes] =
{53,         97,         193,       389,       769,1543,       3079,       6151,      12289,     24593,49157,      98317,      196613,    393241,    786433,1572869,    3145739,    6291469,   12582917,  25165843,50331653,   100663319,  201326611, 402653189, 805306457,1610612741, 3221225473, 4294967291
};inline unsigned long __stl_next_prime(unsigned long n)
{const unsigned long* first = __stl_prime_list;const unsigned long* last = __stl_prime_list + __stl_num_primes;const unsigned long* pos = lower_bound(first, last, n);return pos == last ? *(last - 1) : *pos;
}
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 hashi = 0;for (auto ch : key){hashi *= 131;hashi += ch;}return hashi;}
};namespace open_address
{enum State{EXIST,EMPTY,DELETE};template<class k,class v>struct HashData{pair<k, v> _kv;State _state = EMPTY;};template<class k,class v,class Hash=HashFunc<k>>class HashTable{public:HashTable(size_t size = __stl_next_prime(0)):_n(0), _tables(size){}private:vector <HashData<k, v>> _tables;size_t _n;   // 表中存储数据个数};
}

2)插入操作

  1. 计算键的哈希值,得到初始槽位。

  2. 如果该槽位为空,插入键值对。

  3. 如果该槽位已占用,按照探测序列寻找下一个空槽位。

  4. 重复步骤3,直到找到空槽位或遍历完整个表。

  5.  要注意扩容问题,扩容代价是很大的,不能像顺序表或者链表一样在后面扩容,因为哈希表是具有映射关系的,扩容后要重新映射的

参考代码:

bool Insert(const pair<k, v>& kv)
{if ((double)_n / (double)_tables.size() >= 0.7){// 0.7负载因子就开始扩容//vector<HashData<K, V>> newtables(_tables.size()*2);遍历旧表,重新映射//for (size_t i = 0; i < _tables.size(); i++)//{//	if (_tables[i]._state == EXIST)//	{//		//...//	}//}//HashTable<K, V> newHT(_tables.size()*2);//扩容代价是很大的,不能像顺序表或者链表一样在后面扩容,因为哈希表是具有映射关系的,扩容 后要重新映射的HashTable<k, v, Hash> newHT(__stl_next_prime(_tables.size() + 1));for (size_t i = 0; i < _tables.size(); i++){if (_tables[i]._state == EXIST){newHT.Insert(_tables[i]._kv);}}_tables.swap(newHT._tables);}Hash hs;size_t hash0 = hs(kv.first) % _tables.size();size_t hashi = hash0;size_t i = 1;// 线性探测while (_tables[hashi]._state == EXIST){hashi = (hash0 + i) % _tables.size();++i;}_tables[hashi]._kv = kv;_tables[hashi]._state = EXIST;++_n;return true;
}

3)查找操作

  1. 计算键的哈希值,得到初始槽位。

  2. 检查该槽位是否包含目标键。

  3. 如果包含,返回对应的值。

  4. 如果不包含,按照探测序列继续查找。

  5. 如果遍历完整个表仍未找到,返回空。

 参考代码:

HashData<k, v>* Find(const k& key)
{Hash hs;size_t hash0 = hs(key) % _tables.size();size_t hashi = hash0;size_t i = 1;// 线性探测while (_tables[hashi]._state != EMPTY){if (_tables[hashi]._kv.first == key && _tables[hashi]._state != DELETE){return &_tables[hashi];}hashi = (hash0 + i) % _tables.size();++i;}return nullptr;
}

4)删除操作

  1. 计算键的哈希值,得到初始槽位。

  2. 检查该槽位是否包含目标键。

  3. 如果包含,标记该槽位为已删除(通常使用特殊标记)。

  4. 如果不包含,按照探测序列继续查找。

  5. 如果遍历完整个表仍未找到,返回空。

 参考代码:

bool Erase(const k& key)
{HashData<k, v>* ret = Find(key);if (ret){ret->_state = DELETE;return true;}else{return false;}
}

 4.与哈希桶的对比

1. 工作原理

方法工作原理
开放寻址法当发生冲突时,按照某种探测序列在哈希表中寻找下一个空槽位来存储冲突的键值对。
哈希桶(链地址法)每个桶是一个链表,当发生冲突时,将冲突的键值对插入到对应桶的链表中。

2. 内存使用

方法内存使用
开放寻址法使用单一的桶数组,内存使用效率较高,但需要预留一定的空槽位来处理冲突。
哈希桶每个桶是一个链表,内存使用效率较低,但可以动态扩展链表长度来处理冲突。

3. 查找效率

方法查找效率
开放寻址法查找效率较高,特别是在低负载因子下。高负载因子下冲突频繁,查找效率下降。
哈希桶查找效率取决于链表的长度。链表越长,查找效率越低,但冲突处理较为灵活。

4. 插入效率

方法插入效率
开放寻址法插入效率较高,但需要处理探测序列中的空槽位。
哈希桶插入效率较高,直接将冲突的键值对插入到链表中即可。

5. 删除效率

方法删除效率
开放寻址法删除操作需要特殊处理,通常标记槽位为已删除,不能简单地将槽位设置为nullptr
哈希桶删除操作较为简单,直接从链表中删除对应的键值对即可。

6. 实现复杂度

方法实现复杂度
开放寻址法实现相对简单,但需要处理探测序列和删除操作的特殊标记。
哈希桶实现稍微复杂,需要维护链表结构,但删除操作较为直观。

7. 适用场景

方法适用场景
开放寻址法适用于内存有限或对查找速度要求较高的场景。
哈希桶适用于动态数据或冲突较多的场景,链表可以灵活扩展以处理冲突。

 8.总结

开放寻址法:内存使用效率较高,查找效率在低负载因子下较好,但删除操作需要特殊处理。

哈希桶(链地址法):内存使用效率较低,但冲突处理灵活,删除操作简单,适用于动态数据。

 

http://www.dtcms.com/wzjs/100287.html

相关文章:

  • 网站建设微站上海百度首页优化
  • wordpress手机怎么分享链接天津seo推广优化
  • 邯郸网站制作哪家好石家庄seo推广公司
  • 怎么做网站的关键词库seo一键优化
  • 如何做网站限制石家庄seo公司
  • 如何做超市的网站怎么优化网站关键词排名
  • wordpress工单网站如何做优化推广
  • 网站代码优化视频教程新媒体运营哪个培训机构好
  • 遵义市建设厅网站最近的新闻事件
  • 南阳旅游网 网站设计太原seo关键词排名优化
  • wordpress开通邮箱seo网站关键词优化报价
  • 一个空间怎么放2个网站seo技术培训价格表
  • 西安网站建设专业免费网站建设模板
  • 宁波网站建设-中国互联关键词排名技巧
  • 能帮忙做网站建设宁德市医院
  • 友情链接权重高的网站百度号码认证平台
  • 网站兼容性怎么调seo搜索引擎优化怎么做
  • 网络营销网站郑州seo课程
  • 动漫制作就业方向济源新站seo关键词排名推广
  • 网站关键词选取的方法每日新闻摘抄10一30字
  • 摄影做网站全国防疫大数据平台
  • 外贸营销网站建设公司广西关键词优化公司
  • 网站域名的密码站长之家怎么找网址
  • 企业做增资 网站平台网络营销运营方案
  • 顺德定制网站设计淘宝关键词排名是怎么做的
  • 最专业的网站制作公司搜索引擎营销的方式
  • 大型网站怎么加载图片的快速排名软件seo系统
  • 没有网站怎么做链接视频播放器百度指数查询排行榜
  • 创建免费网站需要什么条件西安区seo搜索排名优化
  • 人和动物做的电影网站seo标题优化步骤