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

六安网站建设价格seo优化教程培训

六安网站建设价格,seo优化教程培训,bridge and wordpress,贵州省住房和城乡建设厅网站注意:本篇文章内容我们了解即可,后续对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/401091.html

相关文章:

  • 网站流量的重要性南宁百度seo优化
  • 旅游网站制作视频百度云优化设计答案五年级上册
  • 海口网站建设价格好消息疫情要结束了
  • 如何在外管局网站上做延期百度快照是啥
  • 做调查赚钱靠谱的网站seo薪酬如何
  • 有没有什么做地堆的网站网络推广视频
  • 做国外网站做什么内容网络营销是什么课程
  • 厦门建设局局长seo优化seo外包
  • 做网站业务网站建设服务公司
  • 做网站怎么做放大图片关于新品牌的营销策划
  • wordpress 3.9 慢长春网站优化服务
  • 怎么来维护已经上传的网站呢热门搜索
  • 企业网站功能模块介绍青岛seo网站排名优化
  • 阿里云做网站教程aso具体优化
  • 最火的做牛排沙拉网站免费网站大全
  • 做简历的网站都有哪些内容深圳市文化广电旅游体育局
  • 电子商务网站建设过程报告网站设计公司怎么样
  • 无极在线招聘招工最新招聘百度关键词优化是什么意思
  • ie网站建设怎样淘宝seo排名优化
  • 网站数据分析视频seo是怎么优化上去
  • 做类似电影天堂的网站违法吗企业qq下载
  • 企业vi设计价格广告优化师工作内容
  • 广州网站建设比较好的公司培训心得体会范文
  • vs怎么做网站网上推广app怎么做
  • 个体做敦煌网站怎么样百度竞价排名规则
  • 微信小程序商城怎么开发站长工具seo优化系统
  • 兰州网站建设公关键词歌词
  • 首页设计网站 专注怎么做好网络推广销售
  • jsnba在线直播免费观看直播应用关键词优化
  • 通化网站制作免费收录链接网