【数据结构】散列(哈希)表简单介绍

        散列表也叫做哈希表(Hash table),散列表通过关键码和存储地址建立唯一确定的映射关系,能够快速查找到对应的元素,排序算法中的计数排序就是一种利用哈希进行排序的算法。

一、散列表的概念

        散列表(Hash table)是表示集合和字典的另一种有效方法,它提供了一种完全不同的存储和搜索方式,通过将关键码映射到表中的某个位置来存储元素,然后根据关键码用同样的方式直接访问。

二、散列方法

        在散列表中搜索元素可以不进行任何大小的比较,只需要支持比较相等即可,因为通过映射关系建立的散列表可以一次从中得到要搜索的元素的集合。

(一)散列函数(Hash function)

        元素在散列表中的存储地址和关键码之间的映射关系通过散列函数Hash()来唯一确定,使得每个关键码在散列表中都有一个唯一确定的存储位置相对应。Address为散列表中距离散列表中第一个存储位置的地址偏移量,key为元素的关键码,那么所确定的存储位置Address和关键码key之间的关系为

                                                Address = Hash(key)

        一般情况,关键码的集合比散列表地址的集合大得多,所以会出现不同元素的关键码通过同一个散列函数计算出了同一个存储位置,这些不同的关键码称之为同义词(synonym)。这些同义词元素在存储时就会发生哈希冲突,冲突往往是不能够避免的,只能尽量减小,所以我们必须有解决冲突的方法,我们也需要选择合适的散列函数,尽量让散列表中的每一个位置都能有相同的概率被不同关键码映射到,减少冲突的发生。

(二)、散列函数的选择

所有的散列函数需要遵循下面三个规定:

1、散列函数的定义域必须包含全部的关键码,并且如果散列表允许存储的地址个数为size个,那么散列函数计算出的映射地址的值域必须为[0,size - 1]。

2、通过散列函数计算出的地址应能够均匀分布在整个地址空间中,让散列表中的每一个位置都能有相同的概率被不同关键码映射到,减少冲突的发生。

3、散列函数应是简单的,能够在较短时间内计算出结果。

         下面来讲一个常用的散列函数,除留余数法其他的散列函数有很多:数学分析法、平方取中法、折叠法等等,这里不着重介绍。

        假设散列表中的存储地址个数为size个,某元素的关键码为key(key需要是整数,如果不是整数类型,则还需要通过某种规则将key转化为整数,例如将字符串按照某种规则转化为整数)。

除留余数法(division)

        取一个质数pp \leqslant size,则可以利用下面的公式将关键码转化为散列地址:

                                                        hash(key) = key % p

       其中,“%”是运算符中的整数除法取余的操作。当p接近于size并且为质数时,散列函数计算出的映射值冲突最小,为更进一步的减小冲突,p也应当避免为2或10的次幂。当然这不是硬性要求,如果不注重极致的效率,自己设计实现的散列表的p可以不为质数,也不管是否为2或10的次幂。为了简单介绍,下面出现的size就等于并代表p。

        举例: size = 10, key = 2233,那么2233通过散列函数映射到的地址offset = hash(2233) = 2233 % 10 = 3。

三、处理冲突的方法

(一)、闭散列(开地址法)

        闭散列也叫做开地址法开一段数组空间作为散列表(hash table),数组的元素类型即需要存储的元素的类型,该数组有size个存储地址,并将该数组头尾相连作为环状结构使用。当新插入一个元素时,用该元素的关键码key计算其存储的位置hashi,然后将该元素定位到散列表中的第hashi个位置上,如果hashi位置尚未存储有其他元素,那么直接将新的元素存储到hashi的位置。若hashi位置已经被其他元素占取了,此时发生了冲突,需要制定某种方案将新插入的元素存储到“下一个”空的位置中。

线性探查法解决哈希冲突

        下面详细讲闭散列中的一种解决哈希冲突的方法:线性探查法(linear probing)。还有其他的解决冲突方法:如二次探查法(quadratic probing)和双散列法,这里不着重介绍

插入元素       

        给出一组元素,它们的关键码分别为37,25,15,36,49,68,59,11,表的大小size = 10。散列函数使用除留余数法,hash(key) = key % 10。

这样可得每一个关键码对应的映射地址为:

关键码(key)

映射地址(hash(key))

37

7

25

5

15

5

36

6

49

9

68

8

59

9

11

1

将上述元素的关键码(为简单起见,键就是要存储的元素值)依次存储到散列表中,散列表中的变化如下: 

        需要加入一个新元素时,通过散列函数计算该元素存储的位置,如果存储的位置存在其他的元素, 则查看紧随其后的下一个位置,如果没有被占用,则将新元素存储到该位置,否则继续查看紧随其后的下一个位置,直到找到没有被占用的位置为止(若饶了数组一圈都没法找到空的位置,说明散列表满了),则插入失败(如果在满之前扩容就可以避免发生因为容量不足而插入失败的情况了)

散列情况统计:

关键码

37

25

15

36

49

68

59

11

映射位置

7

5

5

6

9

8

9

1

冲突位置

5

6,7

8,9

9,0

1

最后存入的位置

7

5

6

8

9

0

1

2

探查次数

1

1

2

3

1

3

3

2

查找元素

        将这些关键码存储到散列表中后,后续查找某元素时的查找次数和存入该元素时的探查次数相同,方式也一样。例如在散列表中搜索关键码为36的元素,先通过散列函数定位到6的位置,发现6号位置为15,不相等,则线性探测到下一号7,7号位置为37,不相等,则线性探测到下一号8,发现相等,此时查找到了关键码为36的元素。若探测到的位置存储的元素为空,则查找失败,该元素不在散列表中。

删除元素 

        需要注意,在闭散列的情形下不能随便物理删除散列表中已有的元素。因为若删除元素会影响其他元素的搜索。例如在上面查找关键码为36的元素例子前,把关键码为37的元素给物理删除了,7号位置为空,那么在查找36时,探测到7号位置,发现为空,此时程序为认为关键码为36的元素不在该散列表中,就发生了漏查的情况,解决方法是对删除的7号位置标记为deleted状态,当查找探测到deleted状态的位置时,继续往下探测,这样就不会发生漏查了

负载因子α

        引入负载因子α来讨论当前散列表是否需要进行扩容,负载因子α的计算方法为:设当前散列表存储的元素个数为n,散列表的大小为size,那么α = n / size。若用线性探查法解决冲突当α = 1时,说明此时散列表满了,不论如何都要进行扩容操作了。采用线性探查法的散列表一般在α 小于等于0.75前就应该扩容了,因为采用线性探查法的散列表存储过多元素会产生太多的“堆积”会导致该散列表的搜索效率过低。

搜索效率

        元素通过关键码可以映射定位到一个接近散列表中存储该元素的位置,能够从接近该元素存储位置的地方开始线性探测,而线性探查法容易产生“堆积(cluster)”问题,即某元素本该映射到的位置被其他的非映射到该位置的元素给占用了,某元素映射到的位置和实际存储的位置不相同,导致插入和搜索时所需要探测的序列长度变长,搜索时间增加。

简单代码实现(C++)

#pragma once
#include <iostream>
#include <vector>using namespace std;//-----------------------------HashFunc仿函数----------------------------------------
// 描述:将键值转化为哈希值(就是将某类型K的关键码转化为整数的方法)
//-----------------------------------------------------------------------------------
template<class K>
class HashFunc
{
public:size_t operator() (const K& key){return (size_t)key;	//对于可以转化为整形的数据直接强转为整形}
};//对常用的string类型进行特化处理,转化为哈希值
template<>
class HashFunc<std::string>
{
public:size_t operator() (const std::string& str){//进行特殊运算将字符串转化为整形映射//其他的转化方法参考https://www.cnblogs.com/-clq/archive/2012/05/31/2528153.htmlsize_t hash = 0;for (auto& e : str){hash += e;hash *= 31;	//每次加上一个ASCII码值再乘上31}return hash;}
};//闭散列开放地址法
//解决哈希冲突的方法:线性探查法
namespace MySpace1
{//-----------------------------存储状态和存储节点的类型的定义------------------------// //-----------------------------------------------------------------------------------//哈希表中每个位置的存储状态enum KindOfState{EMPTY,	//代表该位置为空EXIST,	//代表该位置存在着元素DELETED,};//哈希表的结点,数组的每一个元素为一个结点,里面存储了要存储的元素和该位置状态template<class T>struct HashNode{public:T _data;	//结点存储的数据KindOfState _state;	//该节点的状态HashNode(T data = T(), KindOfState state = EMPTY) :_data(data), _state(state) {  }};//----------------------------------哈希表的具体实现---------------------------------// 描述:博客上的描述和代码实现上可能有些出入。//-----------------------------------------------------------------------------------template<class T, class Hash = HashFunc<T>>class HashTable{private:typedef HashNode<T> Node;vector<Node> _table;	//哈希表size_t currentSize;	//当前哈希表实际存储的数据个数public:HashTable() :currentSize(0){_table.resize(10);	//默认开十个数据大小}//插入bool insert(const T& key){if (_table[find(key)]._state == EXIST)	//判断要插入的值是否已经存在,如果是则插入失败return false;if (currentSize * 100 / _table.size() >= 75)	//负载超过75%就扩容{//扩容和重新映射//两倍扩容HashTable newTable;newTable._table.resize(2 * _table.size());for (auto& e : _table)	//将原有数据插入到新表中重新计算映射位置newTable.insert(e._data);_table.swap(newTable._table);	//将新表交换给旧表,完成扩容工作//cout << "扩容到" << _table.size() << "个数据大小" << endl;}Hash hash;//除留余数法计算哈希值size_t hashi = hash(key) % _table.size();//找到空位存储key值while (_table[hashi]._state == EXIST){hashi = (hashi + 1) % _table.size();}_table[hashi]._data = key;_table[hashi]._state = EXIST;currentSize++;	//存储的有效数据个数+1return true;}//删除bool erase(const T& key){size_t hashi = find(key);if (_table[hashi]._state == EXIST){_table[hashi]._state = DELETED;currentSize--;return true;}return false;}//查找,返回对应关键码的映射位置size_t find(const T& key) const{Hash hash;size_t hashi = hash(key) % _table.size();while (_table[hashi]._state != EMPTY)	//不为空则往后找{if (_table[hashi]._state == EXIST && _table[hashi]._data == key)	//存在且与key相等return hashi;hashi = (hashi + 1) % _table.size();}//找不到return hashi;}};//--------------------------------测试代码------------------------------------// 描述:需要在调试窗口看具体的存储情况//----------------------------------------------------------------------------void test1(){MySpace1::HashTable<int> hashTable;int a[] = { 11,21,4,14,24,15,9 ,55,66,99,87,15,56,61,32,14,14,16 };for (auto e : a){hashTable.insert(e);}hashTable.erase(15);size_t hash = hashTable.find(55);for (auto e : a){hashTable.erase(e);}}void test2(){HashTable<string> hashTable;hashTable.insert("insert");hashTable.insert("sort");hashTable.insert("good");hashTable.insert("oodg");hashTable.insert("rtos");hashTable.insert("sertin");hashTable.insert("dog");hashTable.insert("cat");hashTable.insert("bird");hashTable.erase("good");size_t i = hashTable.find("good");}
};

(二)、开散列 (链地址法)

        开散列也叫做链地址法,开一段数组空间作为散列表(hash table),数组的元素类型为指向一个链表头结点的指针类型(若链表为空,则置空)。散列表中的每一个元素都是一个指针,指向不同的链表,每一个链表都为一个,该结构又叫做哈希桶。当不同的关键码通过同一个散列函数计算出相同的存储位置hashi时,只需将这些互为同义词的元素存储到第hashi位置的桶上,也就是存储在同一个链表上,每一个桶为同义词的集合

插入元素

        给出一组元素,它们的关键码分别为37,25,15,36,49,68,59,11表的大小size = 10。散列函数使用除留余数法,hash(key) = key % 10。

这样可得每一个关键码对应的映射地址为:

关键码(key)

映射地址(hash(key))

37

7

25

5

15

5

36

6

49

9

68

8

59

9

11

1

将上述元素的关键码(为简单起见,键就是要存储的元素值)依次存储到散列表中,散列表中的变化如下: 

查找和删除元素

        查找:待查找的元素x的关键码通过散列函数找到对应的桶号,然后在桶内通过遍历链表的方式依次将遍历的元素和待查找的元素x进行比对即可。

        删除:待删除的元素x的关键码通过散列函数找到对应的桶号,执行像链表一样删除某结点的操作即可。

负载因子α

        引入负载因子α来讨论当前散列表是否需要进行扩容,负载因子α的计算方法为:设当前散列表存储的元素个数为n,散列表的大小为size,那么α = n / size。若用开散列的哈希桶结构解决冲突当α = 1时,建议进行扩容操作,因为当α = 1时,说明n = size,在非常理想的情况下,每个桶的结点都均等分,即哈希表中的所有桶都存储有结点,而且每个桶只有一个结点,这个时候对哈希表进行扩容,可以控制每个桶的长度不会过长,保证搜索效率。当存储的元素非常多时,要追求更高效率,可以在桶的长度超过8时,考虑使用红黑树结构存储同义词的集合,而不是桶结构,保证搜索的时间复杂度为常数级别

搜索效率

        在冲突不多,每个桶存储结点的平均长度不长的时候(必要时可考虑使用红黑树结构代替桶),搜索效率高,时间复杂度可以达到常数级O(1)

        在这个例子中,搜索成功的平均搜索长度为(1 + 1 + 2 + 1 + 1 + 1 + 1 + 2 ) / 8 = 1.25

搜索失败的平均搜索长度为(1 + 2 + 1 + 1 + 1 + 3 + 2 + 2 + 2 + 3) / 10 = 1.8

简单代码实现(C++)

#pragma once
#include <iostream>
#include <vector>using namespace std;//-----------------------------HashFunc仿函数----------------------------------------
// 描述:将键值转化为哈希值(就是将某类型K的关键码转化为整数的方法)
//-----------------------------------------------------------------------------------
template<class K>
class HashFunc
{
public:size_t operator() (const K& key){return (size_t)key;	//对于可以转化为整形的数据直接强转为整形}
};//对常用的string类型进行特化处理,转化为哈希值
template<>
class HashFunc<std::string>
{
public:size_t operator() (const std::string& str){//其他的转化方法参考字符串Hash函数size_t hash = 0;for (auto& e : str){hash += e;hash *= 31;	//每次加上一个ASCII码值再乘上31}return hash;}
};namespace MySpace2
{//桶的结点定义template<class T>struct HashBucketNode{T _data;HashBucketNode* next;	//指向下一个结点,如果为空,则代表尾结点HashBucketNode(const T& data) :_data(data), next(nullptr) {  }};//散列表的具体实现template<class T, class Hash = HashFunc<T>>class HashTable{private:typedef HashBucketNode<T> Node;	vector<Node*> _table;	//散列表为指针数组,每个指针指向一个桶size_t currentSize;	//存储的有效数据个数public:HashTable() :currentSize(0){_table.resize(10, nullptr);	//默认开10个桶的大小,都为空}~HashTable()	//析构函数,释放所有桶的结点{for (auto& node : _table){Node* pCur = node;Node* pNext = nullptr;while (pCur){pNext = pCur->next;delete pCur;pCur = pNext;}node = nullptr;}}//插入bool insert(const T& value){if (find(value))	//如果要插入的元素已经存在,插入失败				return false;if (currentSize >= _table.size())	//如果当前数据个数等于桶的个数,就扩容{vector<Node*> newTable(_table.size() * 2, nullptr);for (auto& node : _table)	//将每个桶里的结点重新映射,将现有节点移动到新的桶中,而不应是复制结点。{if (node)	//该桶不为空{Node* pNext = nullptr;Node* pCur = node;size_t hashi;Hash hash;while (pCur){pNext = pCur->next;hashi = hash(pCur->_data) % newTable.size();	//计算映射值//头插到新的桶中pCur->next = newTable[hashi];newTable[hashi] = pCur;pCur = pNext;}}}//旧表和新表交换_table.swap(newTable);}Hash hash;size_t hashi = hash(value) % _table.size();//将元素头插到桶上Node* newNode = new Node(value);newNode->next = _table[hashi];_table[hashi] = newNode;	//成为新的头结点currentSize++;	//结点的数量增加return true;}//删除bool erase(const T& key){Hash hash;size_t hashi = hash(key) % _table.size();Node* pPrev = nullptr;	//待删除节点的上一个结点Node* pCur = _table[hashi];	//到对应的桶中找对应结点while (pCur){if (pCur->_data == key)break;pPrev = pCur;pCur = pCur->next;}//如果不存在该结点if (!pCur)return false;//如果删除的是头结点if (pPrev == nullptr){_table[hashi] = pCur->next;delete pCur;}else{pPrev->next = pCur->next;delete pCur;}currentSize--;return true;}//查找Node* find(const T& key){Hash hash;size_t hashi = hash(key) % _table.size();Node* pCur = _table[hashi];	//到对应的桶中找对应结点while (pCur){if (pCur->_data == key)return pCur;pCur = pCur->next;}//找不到return	nullptr;}};void test1(){HashTable<int> hsTable;int a[] = { 37,25,15,36,49,68,59,25,15,36,49};for (auto e : a)	//依次添加案例元素{hsTable.insert(e);}for (auto e : a)	//测试依次删除所有元素{hsTable.erase(e);}}
};

       

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/149181.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

一篇大模型Agent记忆机制研究综述

转自&#xff1a;PaperAgent 基于大型语言模型&#xff08;LLM&#xff09;的智能体最近吸引了研究和工业社区的广泛关注。与原始的大型语言模型相比&#xff0c;基于LLM的智能体以其自我进化能力为特色&#xff0c;这是解决需要长期和复杂智能体-环境交互的现实世界问题的基础…

10.安卓逆向-安卓开发基础-api服务接口设计1

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a;图灵Python学院 本人写的内容纯属胡编乱造&#xff0c;全都是合成造假&#xff0c;仅仅只是为了娱乐&#xff0c;请不要盲目相信。 工…

实战精选 | 5分钟利用 OpenVINO™ 部署 Qwen2.5

点击蓝字 关注我们,让开发变得更有趣 作者 | 杨亦诚 英特尔 AI 软件工程师 排版 | 吴紫琴 OpenVINO™ Qwen2.5 是阿里通义团队近期最新发布的文本生成系列模型&#xff0c;基于更富的语料数据集训练&#xff0c;相较于 Qwen2&#xff0c;Qwen2.5 获得了显著更多的知识&#xff…

HSD AIM915 916 芯片调试

在车机显示 系统中&#xff0c;AIM915X和AIM916X作为车机和显示屏之间的传输芯片&#xff0c;车机的LVDS视频信号传到显示屏&#xff1b;控制信号如I2C、GPIO可实现双向透传&#xff1b; 一、设备树 开发平台&#xff1a;IMX6D 1、设备节点 2、timing参数 二、分辨率 1、修改为…

通过企业微信群机器人 发送群消息

1、添加群机器人&#xff0c;复制的webhook地址 2、 public static void main(String[] args) { String reqUrl "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key6xdexxxxxxxxxxxxxxxxxxxxxxxxxxx"; String title "填…

FP7208:升压汽车车灯方案 高效稳定的电力支持

前言 近年来随着汽车的不断普及&#xff0c;车灯方面也在不断发展&#xff0c;车灯对于汽车不仅是外观件更是汽车主动安全的重要组成部分。灯光在保证照亮前部道路的同时&#xff0c;还要确保不对对面车辆产生眩目影响。同时需要针对不同路况和不同载荷引起的灯光偏离进行调整&…

入门数据结构JAVA DS——二叉树的介绍 (构建,性质,基本操作等) (1)

前言 二叉树的概念和性质 二叉树的基本概念 二叉树的种类 二叉树的性质 二叉树的构建存储与遍历 存储 构建 遍历 前序遍历 后序遍历 中序遍历 层序遍历 二叉树的基本操作 获取树中结点个数 获取叶子结点个数 获取第K层结点的个数 获取二叉树的高度 检测值为v…

【新书】从零构建大型语言模型,370页pdf

学习如何从零开始创建、训练和调整大型语言模型&#xff08;LLMs&#xff09; 在《从零构建大型语言模型》一书中&#xff0c;畅销书作者塞巴斯蒂安拉什卡&#xff08;Sebastian Raschka**&#xff09;将一步步指导你创建自己的LLM。每个阶段都有清晰的文字、图表和示例解释。…

【Python】生成dataframe的测试样例,用于测试一个或者多个dataframe

我们在处理dataframe测试时&#xff0c;发现&#xff0c;总需要重新构造一个新的dataframe&#xff0c;每次想找个现成的就想抓狂。 所以&#xff0c;为了方便随用随拿&#xff0c;我在这里直接保存一个直接生成dataframe 的方法。 1. 生成一个随机dataframe的方法&#xff1…

1688店铺装修模板1688店铺怎么装修1688装修模板1688店铺装修教程视频1688运营阿里巴巴店铺装修设计阿里店铺首页怎么装修产品分类效果

侧边栏装修效果&#xff0c;代码1688店铺怎么装修1688装修模板1688店铺装修教程视频1688运营阿里巴巴店铺装修设计阿里店铺首页怎么装修 工具是一秒美工助手

食家巷苦豆粉,香得很哟

苦豆粉&#xff0c;它看似普通&#xff0c;却承载着西北的厚重历史与浓郁风情。那一抹淡淡的绿色粉末&#xff0c;蕴含着大自然的馈赠和西北人民的智慧。 苦豆&#xff0c;这种生长在西北土地上的植物&#xff0c;经过精心研磨&#xff0c;变成了细腻的苦豆粉。它的味道独特&am…

python对文件的写入和追加

写入文件 1.打开文件 文件可以是不存在的&#xff0c;不存在就会创建 f open(./test.txt, w, encoding"utf-8")2.写数据到内存中 f.write("你好&#xff0c;世界")3.写到硬盘中 f.flush()#或者 close()有刷新的功能 f.close()整体代码 #打开文件 f …

鲲鹏计算这五年:硬生态基本盘稳住,才能放手进击软生态

文 | 智能相对论 作者 | 叶远风 数智化深入发展、新质生产力成为主旋律的当下&#xff0c;本土计算产业的发展被寄予越来越多的关注和期待。自2019年开启以来&#xff0c;鲲鹏计算产业生态已经整整走过5个年头。 因此&#xff0c;今年华为全联接大会的鲲鹏之夜&#xff0c;在…

还在用windows自带录屏?试试这三款录屏工具

作为一名办公室文员&#xff0c;我经常需要录制电脑屏幕来制作教程或者记录工作流程。在众多的录屏工具中&#xff0c;我尝试了四款不同的录屏工具&#xff0c;包括Windows自带录屏工具。今天&#xff0c;我就来跟大家分享一下我的使用体验&#xff0c;希望能帮助到和我有同样需…

在视频上绘制区域:使用Vue和JavaScript实现交互式画布

在数字时代&#xff0c;交互式媒体内容的创建和消费变得越来越普遍。特别是视频内容&#xff0c;它不仅提供了视觉信息&#xff0c;还允许用户与之互动&#xff0c;从而增强了用户体验。本文将介绍如何使用Vue.js框架和JavaScript创建一个交互式组件&#xff0c;该组件允许用户…

谷歌老户的优势及优化策略,增加曝光度方法介绍

谷歌老户&#xff08;已存在一段时间并积累了历史数据的账户&#xff09;通常具有较高的权重和稳定性&#xff0c;这使其在投放广告时可以更快速地增加流量并保持稳定的表现。以下是一些策略和建议&#xff0c;帮助您最大化利用谷歌老户的优势。 一、它的优势&#xff1a; 账…

Cherry Studio:开启AI智能工作的新篇章

引言 在当今快速发展的科技时代&#xff0c;如何高效利用人工智能技术提升工作效率&#xff0c;成为了各行各业专业人士的共同追求。&#x1f352; Cherry Studio 正是为此而生&#xff0c;它是一款支持多模型服务的桌面客户端&#xff0c;内置了超过 30 个行业的智能助手&…

MDS130-16-ASEMI充电桩专用MDS130-16

编辑&#xff1a;ll MDS130-16-ASEMI充电桩专用MDS130-16 型号&#xff1a;MDS130-16 品牌&#xff1a;ASEMI 封装&#xff1a;DXT-5 批号&#xff1a;2024 现货&#xff1a;50000 最大重复峰值反向电压&#xff1a;1600V 最大正向平均整流电流(Vdss)&#xff1a;130A …

VOC2007数据集

目标检测入门code 文件目录 下载数据集——在官网下载VOC2007数据集 下载训练数据集 TRAIN data 下载测试数据集 TEST data 解压数据集 解压——训练数据集&#xff0c;在服务器上&#xff0c;目录为VOCdevkit 部分文件目录 全部文件总目录 解压——测试数据集 &#xff08;…

828华为云征文|云服务器Flexus X实例评测体验之搭建MySQL数据库

全文目录&#xff1a; 一、前言二、Flexus X云服务器2.1 Flexus X实例概述2.2 为什么选择 Flexus X实例&#xff1f; 三、购选及登录教程3.1 如何选购Flexus X&#xff1f;3.2 登录方式选择 四、安装 MySQL4.1 安装MySQL依赖库4.2 下载MySQL安装包4.3 上传MySQL安装包4.4 解压M…