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

六安网站建设价格百度站长工具收费吗

六安网站建设价格,百度站长工具收费吗,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/364901.html

相关文章:

  • 太原网站建设优化百度品牌广告是什么
  • 西安做网站 好运网络南京网络推广公司排名
  • 乐山市建设银行网站推广网站
  • 如何编写网站建设销售的心得今日新闻头条新闻今天
  • seo是什么工作seo网络优化日常工作内容
  • 桂林北站到阳朔怎么坐车网络营销五个特点
  • 旅游网站开发的背景和意义南京seo关键词排名
  • wordpress写主题seo网站优化培训怎么做
  • 上海新闻官网windows优化大师好不好
  • 古建设计素材网站免费的网络营销方式
  • 做机械的老板都看什么网站河南关键词排名顾问
  • 西宁网站制作多少钱灰色行业推广平台
  • 招聘网站开发计划网站制作流程图
  • 设计网站包含的功能模块网络营销岗位有哪些
  • 制作精美网站建设售后完善seo流量的提升的软件
  • 南阳做网站价格阿里指数查询官网
  • 分模板网站和定制网站网站建设公司网站
  • 有没有专门做数据分析的网站网络营销和传统营销的关系
  • 教学成果奖网站建设广州企业推广
  • 网站维护内容手机百度app免费下载
  • 前端一个页面多少钱seo优化主要工作内容
  • 一个工厂做网站有用吗威海seo优化公司
  • 网站建设基本流程是什么aso苹果关键词优化
  • 做淘宝优惠网站步骤优化大师win7官方免费下载
  • 一个网站推广百度信息流推广教程
  • 南昌建设公司网站网站目录扫描
  • 做爰真实网站如何制作自己的公司网站
  • 往公众号里放网站怎么做太原网站快速排名提升
  • 新手学做免费网站廊坊seo排名外包
  • 网站结构优化包括什么自媒体135免费版下载