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

网站建设项目清单价格大安网站建设

网站建设项目清单价格,大安网站建设,什么情况下需要建设网站,seo的概念哈希冲突解决 上一篇博客提到了#xff0c;哈希函数的优化可以减小哈希冲突发生的可能性#xff0c;但无法完全避免。本文就来探讨一下解决哈希冲突的两种常见方法#xff1a;闭散列和开散列 1.闭散列 闭散列也叫开放定址法#xff0c;发生哈希冲突时#xff0c;如果哈…哈希冲突解决 上一篇博客提到了哈希函数的优化可以减小哈希冲突发生的可能性但无法完全避免。本文就来探讨一下解决哈希冲突的两种常见方法闭散列和开散列 1.闭散列 闭散列也叫开放定址法发生哈希冲突时如果哈希表未被装满说明在哈希表中必然还存在空位置那么就可以把key存放到冲突位置的下一个空位置中去。那如何寻找下一个空位置呢 1.1线性探测 插入的情况 还是上述这种情况当我想插入元素13时通过哈希函数计算出哈希地址为3但此时该位置已经存放了元素3发生了哈希冲突。 进行线性探测从发生冲突的位置开始依次向后探测直到寻找到下一个空位置。 由于下标4、5都有元素存放此时找到的空位置下标为6于是在下标6处存放元素13。 但是哈希表中的空间终究是有限的空间不够时我们需要进行扩容。但如果等到表被填满再进行扩容的话这样一来搜索的时间复杂度更趋向于O(N)了因为表中数据存放越满理论哈希地址与实际哈希地址相隔越远最坏情况就近乎O(N)。所以我们需要更早地进行扩容。我们规定在什么情况下进行扩容呢这里要引入一个载荷因子的概念。 散列表的载荷因子 α 表中的元素个数 / 散列表的长度 载荷因子标记了需要进行扩容的情况。我们可以得知载荷因子α越大散列表越满而散列表越满产生冲突的可能性越大反之α越小产生冲突的可能性越小。但是不是载荷因子越小越好呢并不是载荷因子太小会造成空间的极大浪费因此对于开放定址法载荷因子应限制在0.7-0.8 之间。也就是散列表的空间被利用了70%-80%时就可以进行扩容了。 扩容之后由于地址数增加了关键码通过哈希函数求得的哈希地址也随之改变了所以需要改变映射关系改变映射关系之后原先冲突的元素可能就不再冲突了 原先元素13元素17分别和元素3元素7发生冲突但是扩容之后映射关系重新调整它们就不再冲突了这就是为什么即使哈希结构不能完全保证搜索的时间复杂度为O(1)但也可以近似于O(1)。 搜索的情况 搜索元素时同样将关键码通过哈希函数计算出理论上的哈希地址但是该地址处可能发生哈希冲突若发生哈希冲突则需要继续向后探测当我们遇到空时探测结束说明搜索失败。 但是碰到下面这种情况呢 我们搜索的目标元素是13由于13前一个位置的元素25被删除该位置为空所以会导致探测失败但实际上13是存在的。所以我们在采用闭散列处理哈希冲突时不能随意对已有元素进行物理删除若直接删除会影响其他元素的搜索。因此线性探测采用标记的的伪删除法来删除元素。 对哈希表每个空间给个标记 EMPTY此位置空 EXIST此位置已经有元素 DELETE元素已经删除 enum State{EMPTY, EXIST, DELETE}; 在删除元素时只需要把该哈希位置的标记从 EXIST 改成 DELETE 即可 在搜索元素时探测到标记为 EMPTY 位置时停止表示探测失败。 这样一来就完美解决了上述问题。 线性探测的代码实现 templateclass K struct HashFunc {size_t operator()(const K key){return (size_t)key;} };// 哈希表中支持字符串的操作 template struct HashFuncstring {size_t operator()(const string key){size_t hash 0;for (auto e : key){hash * 31;hash e;}return hash;} };// 以下采用开放定址法即线性探测解决冲突 namespace open_address {enum State{EXIST,EMPTY,DELETE};templateclass K, class Vstruct HashData{pairK, V _kv;State _state EMPTY;};templateclass K, class V, class HashFunc HashFuncKclass HashTable{public:HashTable(){_table.resize(10);}bool Insert(const pairK, V kv){// 根据装载因子决定是否扩容if (_n * 10 / _table.size() 7){// 平衡因子0.7需要扩容扩容后需要重新插入size_t newSz _table.size() * 2;HashTableK, V, HashFunc newHT;newHT._table.resize(newSz);for (size_t i 0; i _table.size(); i){if (_table[i]._state EXIST)newHT.Insert(_table[i]._kv);}_table.swap(newHT._table);}// 插入过程HashFunc hf;size_t hashi hf(kv.first) % _table.size();while (EXIST _table[hashi]._state){hashi;hashi % _table.size();}_table[hashi]._kv kv;_table[hashi]._state EXIST;_n;return true;}HashDataK, V* Find(const K key){HashFunc hf;size_t hashi hf(key) % _table.size();while (_table[hashi]._state ! EMPTY){if (_table[hashi]._kv.first key)return _table[hashi];}return nullptr;}bool Erase(const K key){if (Find(key)){Find(key)-_state DELETE;return true;}return false;}void Print(){for (size_t i 0; i _table.size(); i){if (_table[i]._state EXIST)cout i - _table[i]._kv.first , _table[i]._kv.second endl;elsecout i - NULL endl;}}private:vectorHashDataK, V _table;size_t _n 0; // 表中存储数据个数}; }1.2二次探测 线性探测的缺陷是产生冲突的数据堆积在一块这与其找下一个空位置有关系因为找空位置的方式是挨个往后去找。二次探测就避免了这个问题在二次探测中若初始哈希位置 Hash(Key) h 已被占用则探测下一个位置的公式为h(i) (h i^2) % m其中i 1,2,3,...。 插入元素13时与元素3产生冲突通过二次探测找到新的哈希位置7进行插入。  2. 开散列 概念 开散列法又叫链地址法(开链法)它解决哈希冲突的办法是将具有相同哈希地址的元素通过单链表链接而哈希表中存放的是各链表的头节点。 插入的情况 初始哈希表中存放都是空指针。需要进行元素插入时首先根据哈希函数计算出对应的哈希地址然后为该元素开辟一块地址空间存放元素数据_data 以及_next指针用于链接冲突的元素 如果该哈希地址为空则存放元素节点指针 如果当前地址发生哈希冲突则使用头插的方法即新节点的_next指针指向旧节点哈希表中更新头结点指针 与开散列不同的是由于插入的元素通过单链表的方式进行链接哈希表中只需要存放各链表头结点指针所以哈希表不需要扩容就可以实现任意元素的插入。但是不要忘记我们的初衷哈希表是为了提高数据的搜索效率的因此我们需要控制链表的长度链表越长搜索效率越低下原理和闭散列一样也是通过对哈希表扩容实现元素的分散存储。 在开散列中我们通常将载荷因子定为1 即表中元素个数等于散列表长度时进行扩容。扩容之后需要更新哈希地址重新进行存储。 下面是扩容后的情况仅演示地址更新情况其实该散列还不需要扩容 删除的情况 删除指定元素时我们需要对该元素存放节点进行空间释放释放后要注意更新链表的链接情况  代码实现 #pragma once #includeiostream using namespace std; #includestring #includevector// 哈希函数采用除留余数法 templateclass K struct HashFunc {size_t operator()(const K key){return (size_t)key;} };// 哈希表中支持字符串的操作 template struct HashFuncstring {size_t operator()(const string key){size_t hash 0;for (auto e : key){hash * 31;hash e;}return hash;} };namespace hash_bucket {templateclass K, class Vstruct HashNode{pairK, V _kv;HashNodeK, V* _next;HashNode(const pairK, V kv):_kv(kv), _next(nullptr){}};templateclass K, class V, class HashFunc HashFuncKclass HashTable{typedef HashNodeK, V Node;public:HashTable(){_table.resize(10, nullptr); // 显式初始化}~HashTable(){for (size_t i 0; i _table.size(); i){Node* cur _table[i];while (cur){Node* next cur-_next;delete cur;cur next;}_table[i] nullptr;}_n 0;}bool Insert(const pairK, V kv){if (Find(kv.first))return false;HashFunc hf;// 根据装载因子决定是否扩容if (_n _table.size()){size_t newSz _table.size() * 2;vectorNode* newTB ;newTB.resize(newSz, nullptr);for (size_t i 0; i _table.size(); i){Node* cur _table[i];while (cur){Node* next cur-_next;// 头插到新表size_t newi hf(cur-_kv.first) % newSz;cur-_next newTB[newi];newTB[newi] cur;cur next;}_table[i] nullptr;}_table.swap(newTB);}// 插入操作size_t hashi hf(kv.first) % _table.size();Node* newNd new Node(kv);newNd-_next _table[hashi];_table[hashi] newNd;_n;return true;}Node* Find(const K key){HashFunc hf;size_t hashi hf(key) % _table.size();Node* cur _table[hashi];while (cur){if (cur-_kv.first key)return cur;cur cur-_next;}return nullptr;}bool Erase(const K key){HashFunc hf;size_t hashi hf(key) % _table.size();Node* cur _table[hashi];if (!cur)return false;if ( cur-_kv.first key){_table[hashi] cur-_next;return true;}Node* prev _table[hashi];cur cur-_next;while (cur){if (cur-_kv.first key){prev-_next cur-_next;delete cur;cur nullptr;return true;}cur cur-_next;prev prev-_next;}return false;}void Print(){for (size_t i 0; i _table.size(); i){if (_table[i]){cout i ;Node* cur _table[i];while (cur){cout --( cur-_kv.first , cur-_kv.second );cur cur-_next;}}elsecout i --NULL;cout endl;}}private:vectorNode* _table; // 指针数组size_t _n 0; // 存储了多少个有效数据}; } 以上就是对哈希冲突的两种常见解决办法的介绍欢迎在评论区留言码文不易觉得这篇博客对你有帮助的可以点赞收藏关注支持一波~
http://www.dnsts.com.cn/news/3371.html

相关文章:

  • 网站建设sem账户搭建小程序开发公司十大排名
  • 网站域名在哪里自己创建网站怎么得流量钱
  • wix网站做图片能折叠吗网站实现中英文
  • 企业网站建设需注意点重庆建设银行网站首页
  • 阿里云服务器上传网站网站改版专题页
  • 做名片的网站图书馆信息化网站建设
  • 爱看视频的网站仙桃网站定制
  • 长春做网站哪家好网站品牌词优化怎么做
  • 门户网站建站wordpress插件ERP
  • 湖南网站建设开发wordpress域名配置
  • 网站建设文件夹结构免费学校网站模板html
  • 北京公司网站制作费用可以做请柬的网站
  • 高端网站设计制作方法如何申请网站空间和域名
  • 一键制作免费网站的app大庆免费网站建设公
  • 上海整站优化群晖 搭建wordpress
  • 网站建设企业谁家好wordpress侧边栏美化
  • 自助搜优惠券网站怎么做的网站开发从整体上
  • 电子商务网站设计分析怎么做广州 网站建设公司
  • 晋中市住房与城乡建设厅网站湖南旅游
  • 济宁网站建设哪家便宜江门网站推广设计
  • 传媒网站源码带手机建设部中国建造师网查询
  • 域名拍卖网站婚礼礼网站如何做的
  • 搭积木建网站软件建网站需要哪些技术
  • 帝国cms网站地图生成器怎么接外贸订单
  • 建站工具搭建前台网站wordpress网页psd下载
  • qq查冻结网站怎么做什么是网络营销?网络营销与电商营销有什么区别?
  • 万远翔网站建设建什么网站能百度收录
  • wordpress网站防采集威海seo公司
  • 河北建设厅网站电话建筑网站绿地新里城
  • 广州网站平台怎么做中铁建设集团有限公司领导名单