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

青岛外贸网站运营哪家好收录好的网站

青岛外贸网站运营哪家好,收录好的网站,百度云盘做网站空间,西安学校网站建设哪家好【c】【STL】unordered_set 底层实现总结 我大概花了一个图 总结了一下 (ps:我自己看的不保证完全正确) ps:我写这个的初衷 是想确定 1 c11里面的unordered_set是否存在红黑树这个数据结构–>否 2 他的扩容是怎样设计的–>rehash 3 内…

【c++】【STL】unordered_set 底层实现总结

我大概花了一个图 总结了一下 (ps:我自己看的不保证完全正确)
ps:我写这个的初衷 是想确定
1 c++11里面的unordered_set是否存在红黑树这个数据结构–>否
2 他的扩容是怎样设计的–>rehash
3 内部的扩容因子究竟是多少–>1.0(最大扩容因子)
大概解决这几个问题 并不是整个 unordered_set的内部结构
这个图是大概总结了一下调用逻辑 下面写一下

在这里插入图片描述

1继承关系

template <class _Kty, class _Hasher = hash<_Kty>, 
class _Keyeq = equal_to<_Kty>, class _Alloc = allocator<_Kty>>
class unordered_set : 
public _Hash<_Uset_traits<_Kty, 								  _Alloc, false>>_Uhash_compare<_Kty, _Hasher, _Keyeq>,
参数解释例子
_Kty存储的键的类型int,
_Hasher哈希函数std::hash<int>
_Keyeq键比较器std::equal_to<int>
_Alloc分配器std::allocator<int>
false是否允许重复键(为 false 表示不允许)unordered_set 需要唯一键

unordered_set :

  • 公有继承 _hash (_hash 是实际的哈希表实现,包含哈希冲突解决、扩容等核心逻辑。)
  • _hash<> 是一个 模板内部 是 _Uset_traits<> 模板 (_Uset_traits 负责设置哈希表的行为)
  • Uset_traits <> 是一个模板内部是 _Kty, _Uhash_compare<_Kty, _Hasher, _Keyeq>, _Alloc, false
  1. _hash<T>

    • _hash 是一个类模板,它接收一个模板参数T
    • 这里的 T_Uset_traits<_Kty, _Uhash_compare<_Kty, _Hasher, _Keyeq>, _Alloc, false>
  2. _Uset_traits<T>

    • _Uset_traits 是一个模板,它接收一个模板参数T,用于封装 unordered_set 相关的类型信息
    • 这里的 T_Kty, _Uhash_compare<_Kty, _Hasher, _Keyeq>, _Alloc, false
      • _Kty:键类型(Key Type)。
      • _Uhash_compare<_Kty, _Hasher, _Keyeq>:封装哈希函数 _Hasher 和键比较器 _Keyeq
      • _Alloc:内存分配器(Allocator)。
      • false:是否允许重复键(为 false 表示不允许)。
  3. _Uhash_compare<T>

    • _Uhash_compare 是一个模板,它接收一个模板参数T,负责哈希和比较
    • 这里的 T_Kty, _Hasher, _Keyeq
    • _Uhash_compare 是构造哈希表的关键:

_Uhash_compare<>

1 内部存在 _Mypair 这个对象:

 _Compressed_pair<_Hasher, _Compressed_pair<_Keyeq, float>> _Mypair;
参数作用
_Kty关键字类型(key type)
_Hasher哈希函数类型
_Keyeq键值比较器类型
  • 通过一个 pair(即 _Compressed_pair)存储哈希函数 + 键值比较器,最大负载因子(即扩容因子)。
  • _Mypair结构:
    在这里插入图片描述
    构造函数初始化 最大负载因子 _Mypair._Myval2._Myval20.0f

2 内部定义 bucket_size初始值

template <class _Kty, class _Hasher, class _Keyeq>
class _Uhash_compare: public _Uhash_choose_transparency<_Kty, _Hasher, _Keyeq> { // traits class for unordered containers
public:enum { // parameters for hash tablebucket_size = 1 // 0 < bucket_size};

扩容部分

ps: unordered_set 第一次触发扩容后,内部会将最大负载因子设置成 1.0
涉及内容:
实际负载因子 : 根据计算得出–>元素数量/桶数量(内部写的是_Vec 应该是vector但是我没进去看看实际的···)(0.5–1.0区间)
最大负载因子 :_Mypair._Myval2._Myval2 -->不会显式修改

rehash扩容代码

 void rehash(size_type _Buckets) { // rebuild table with at least _Buckets buckets// don't violate a.bucket_count() >= a.size() / a.max_load_factor() invariant:_Buckets = (_STD max) (_Min_load_factor_buckets(_List.size()), _Buckets);if (_Buckets <= _Maxidx) { // we already have enough buckets; nothing to doreturn;}_Forced_rehash(_Buckets);}
  • _Min_load_factor_buckets(_List.size())–>通过当前最大负载因子 计算出存储元素所需要的最小桶数量
  • _Buckets = (_STD max) (_Min_load_factor_buckets(_List.size()), _Buckets);–>_Buckets是传入的_Buckets值 和 _Min_load_factor_buckets(_List.size())值计算出的较大者
  • if (_Buckets <= _Maxidx)–>如果 _Buckets <= _Maxidx直接返回,否则进行扩容处理(_Forced_rehash(_Buckets);)

_Forced_rehash

_Forced_rehash() 是 unordered_set触发扩容(rehash)时的核心操作。

工作原理(整体思路)

  1. 计算新的桶数量(满足最小的,根据 rehash内部调用传入的_Buckets值),位运算–>将桶数量调整为最接近的 2 的幂log2(x)
  2. 如果桶数量超过最大允许数量,抛出异常。
  3. 重新分配存储空间。
  4. 将所有元素从旧桶重新分配到新桶(按照新的哈希分布)。
  5. 调整哈希表元信息(掩码、最大桶索引等)。

ps:通过位运算提高索引定位效率:定位桶索引采用位运算(&)而不是取模(%)

  • 位运算速度远高于取模运算
  • hash % bucket_size → hash & (bucket_size - 1)
    当桶的数量(即 bucket_size)是 2 的幂时,hash % bucket_size
    hash & (bucket_size - 1)得到的结果是相同的:

关键操作定位

步骤关键操作解释
调整桶数量_Ceiling_of_log_2()调整到 2 的幂次方
分配内存_Assign_grow()分配新桶
更新索引_Mask = _Buckets - 1设置新桶索引的位掩码
重新插入_Mylist::_Scary_val::_Unchecked_splice()将元素插入到桶中
更新桶指针_Bucket_lo = _Inserted更新桶起始位置

测试代码:

#include <iostream>
#include <unordered_set>
#include <string>
using namespace std;int main()
{// 创建空 unordered_set 容器unordered_set<int> uset;cout << "uset 桶数: " << uset.bucket_count() << endl;cout << "uset 当前负载因子: " << uset.load_factor() << endl;cout << "uset 最大负载因子: " << uset.max_load_factor() << endl;cout << "-------设置 uset 使用最适合存储 9 个元素的桶数------" << endl;uset.reserve(9);cout << "uset 桶数: " << uset.bucket_count() << endl;cout << "uset 当前负载因子: " << uset.load_factor() << endl;cout << "uset 最大负载因子: " << uset.max_load_factor() << endl;cout << "-------向 uset 容器添加 4 个元素------" << endl;uset.insert(1);uset.insert(2);uset.insert(7);uset.insert(8);cout << "uset 桶数: " << uset.bucket_count() << endl;cout << "uset 当前负载因子: " << uset.load_factor() << endl;cout << "uset 最大负载因子: " << uset.max_load_factor() << endl;cout << "------------------------------" << endl;// 调用 bucket() 获取指定元素所在的桶编号cout << "元素1 位于桶的编号为: " << uset.bucket(1) << endl;// 使用 hash_function() 自行计算元素所在桶的编号auto fn1 = uset.hash_function();cout << "计算元素1 位于桶的编号为: " << fn1(1) % uset.bucket_count() << endl;// 调用 bucket() 获取指定元素所在的桶编号cout << "元素2 位于桶的编号为: " << uset.bucket(2) << endl;// 使用 hash_function() 自行计算元素所在桶的编号auto fn2 = uset.hash_function();cout << "计算元素2 位于桶的编号为: " << fn2(2) % uset.bucket_count() << endl;// 调用 bucket() 获取指定元素所在的桶编号cout << "元素7 位于桶的编号为: " << uset.bucket(7) << endl;// 使用 hash_function() 自行计算元素所在桶的编号auto fn = uset.hash_function();cout << "计算元素7 位于桶的编号为: " << fn(7) % uset.bucket_count() << endl;return 0;
}

测试结果:
在这里插入图片描述
可以看出 默认桶数 为 8

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

相关文章:

  • 哪类型网站容易做2020年度关键词有哪些
  • 海伦网站建设中国建设网官方网站
  • 创世通网站建设电子商务营销方法
  • 企业商务网站有哪些seo站长工具推广平台
  • 重庆双八自助建设网站如何在各种网站投放广告
  • 怎么做付费的小说网站上海网站推广广告
  • 网站有哪些漏洞网店推广的作用是
  • sns网站建设哪家公司好如何建网站赚钱
  • 网站建设的公司附近电商培训班
  • 想做cpa 没有网站怎么做长春网站建设 4435
  • wordpress 留言本优化是什么梗
  • 现在都是用什么做网站营业推广促销方式有哪些
  • 深圳品牌创意网站建设电商seo名词解释
  • 电商类网站建设需要多少钱深圳全网推广托管
  • 做网站卖广告谷歌seo网站优化
  • 国外流行的内容网站seo排名优化推广
  • 网站打不开怎么做百度 竞价排名
  • 电子商务网站基础建设新闻投稿
  • 有价值 网站免费建网站软件下载
  • 开发手机网站教程可口可乐搜索引擎营销案例
  • 婚纱摄影行业网站北京seo顾问外包
  • 胶南市场建设服务中心网站百度广告一天多少钱
  • 用wordpress做站群手机百度网址大全首页
  • 电子商务网站建设新闻大连seo优化
  • 自己如何建设网站优化外包服务公司
  • 织梦网站地图插件utf-8关键词seo
  • 重庆网络推广外包泰安seo排名
  • wordpress dux 1.6萧山市seo关键词排名
  • 买房咨询平台在线seo手机关键词排行推广
  • wordpress 数据库账号廊坊推广seo霸屏