哈希表/哈希冲突及解决方法(较全)

2023-05-16

哈希表的概念请参阅他人文章,关于哈希冲突的解决这篇文章基本都整理到了,还有几个常见的面试题。

解决hash冲突的几种方法

  • 前导(题外话):
  • 一.开放定址法(闭散列)
    • 1.线性探测再散列
    • 2.二次探测再散列
    • 3.伪随机探测再散列
  • 二.再哈希法
  • 三.链地址法(开散列)
  • 四.建立公共溢出区
  • 五.优缺点(重要)
    • 1.开放散列(open hashing)/ 拉链法(针对桶链结构)
    • 2.封闭散列(closed hashing)/ 开放定址法

前导(题外话):

哈希表的几个概念:

映像:由哈希函数得到的哈希表是一个映像

冲突:如果两个关键字的哈希函数值相等,这种现象称为冲突。

关于哈希函数的选取,可以参见 这篇文章;

另外常见的字符串哈希函数及c++代码实现可以看这里。

主要有:常用的字符串Hash函数还有ELFHash,APHash等等,都是十分简单有效的方法。这些函数使用位运算使得每一个字符都对最后的函数值产生影响。另外还有以MD5SHA1为代表的杂凑函数,这些函数几乎不可能找到碰撞。
常用字符串哈希函数有BKDRHash,APHash,DJBHash,JSHash,RSHash,SDBMHash,PJWHash,ELFHash等等。

BKDRHash无论是在实际效果还是编码实现中,效果都是最突出的。APHash也是较为优秀的算法。DJBHash,JSHash,RSHash与SDBMHash各有千秋。PJWHash与ELFHash效果最差,但得分相似,其算法本质是相似的。

好了,进入正题:
通过构造性能良好的哈希函数,可以减少冲突,但一般不可能完全避免冲突,因此解决冲突是哈希法的另一个关键问题。创建哈希表和查找哈希表都会遇到冲突,两种情况下解决冲突的方法应该一致。下面以创建哈希表为例,说明解决冲突的方法。常用的解决冲突方法有以下四种:

一.开放定址法(闭散列)

开放定址法
这种方法也称再散列法,其基本思想是:当关键字key的哈希地址p=H(key)出现冲突时,以p为基础,产生另一个哈希地址p1,如果p1仍然冲突,再以p为基础,产生另一个哈希地址p2,…,直到找出一个不冲突的哈希地址pi ,将相应元素存入其中。
查找时探查到开放的 地址则表明表中无待查的关键字,即查找失败
这种方法有一个通用的再散列函数形式:
Hi=(H(key)+di)% m i=1,2,…,n
其中H(key)为哈希函数,m 为表长,di称为增量序列。增量序列的取值方式不同,相应的再散列方式也不同。
在这里插入图片描述
这里只给出大致的思想,更详细的具体步骤和代码可以参见这里:
哈希表的原理及解决冲突的方法
另外,散列表的查找性能,一般有两种方法,具体可以看上面这篇文章介绍。

成功平均查找长度(ASLs)
ASLs: 查找表中关键词的平均查找比较次数(其冲突次数加1)
不成功平均查找长度 (ASLu)
ASLu:不在散列表中的关键词的平均查找次数(不成功)
一般方法:将不在散列表中的关键词分若干类。

解决哈希冲突主要有以下三种:

1.线性探测再散列

线性探测再散列
dii=1,2,3,…,m-1(m是tablesize
这种方法的特点是:冲突发生时,顺序查看表中下一单元,直到找出一个空单元或查遍全表。

2.二次探测再散列

二次探测再散列
di=12,-12,22,-22,…,k2,-k2 (2是平方) ( k<=m/2 )
这种方法的特点是:冲突发生时,在表的左右进行跳跃式探测,比较灵活。
(坏处是只能探测到哈希表长度的一半,会浪费一定空间,但若是真的探测到一半的位置了,说明哈希函数的设置有问题,应重选哈希函数)

3.伪随机探测再散列

伪随机探测再散列
di=伪随机数序列。

具体实现时,应建立一个伪随机数发生器,(如i=(i+p) % m),并给定一个随机数做起点。
例如,已知哈希表长度m=11,哈希函数为:H(key)= key % 11,则H(47)=3,H(26)=4,H(60)=5,假设下一个关键字为69,则H(69)=3,与47冲突。
如果用线性探测再散列处理冲突,下一个哈希地址为H1=(3 + 1)% 11 = 4,仍然冲突,再找下一个哈希地址为H2=(3 + 2)% 11 = 5,还是冲突,继续找下一个哈希地址为H3=(3 + 3)% 11 = 6,此时不再冲突,将69填入5号单元。
如果用二次探测再散列处理冲突,下一个哈希地址为H1=(3 + 12)% 11 = 4,仍然冲突,再找下一个哈希地址为H2=(3 - 12)% 11 = 2,此时不再冲突,将69填入2号单元。
如果用伪随机探测再散列处理冲突,且伪随机数序列为:2,5,9,………,则下一个哈希地址为H1=(3 + 2)% 11 = 5,仍然冲突,再找下一个哈希地址为H2=(3 + 5)% 11 = 8,此时不再冲突,将69填入8号单元。

二.再哈希法

再哈希法
这种方法是同时构造多个不同的哈希函数:
Hi=RH1(key) i=1,2,…,k
当哈希地址Hi=RH1(key)发生冲突时,再计算Hi=RH2(key)……,直到冲突不再产生。这种方法不易产生聚集,但增加了计算时间。

三.链地址法(开散列)

链地址法
这种方法的基本思想是将所有哈希地址为i的元素构成一个称为同义词链的单链表,并将单链表的头指针存在哈希表的第i个单元中,因而查找、插入和删除主要在同义词链中进行。链地址法适用于经常进行插入和删除的情况。

将所有关键字为同义词的结点链接在同一个单链表中。若选定的散列表长度为m,则可将散列表定义为一个由m个头指针组成的指针数
组T[0…m-1]。凡是散列地址为i的结点,均插入到以T[i]为头指针的单链表中。T中各分量的初值均应为空指针。

介绍和代码实现

四.建立公共溢出区

建立公共溢出区
这种方法的基本思想是:将哈希表分为基本表和溢出表两部分,凡是和基本表发生冲突的元素,一律填入溢出表。

五.优缺点(重要)

1.开放散列(open hashing)/ 拉链法(针对桶链结构)

开放散列(open hashing)/ 拉链法(针对桶链结构)

1)优点: ①对于记录总数频繁可变的情况,处理的比较好(也就是避免了动态调整的开销) ②由于记录存储在结点中,而结点是动态分配,不会造成内存的浪费,所以尤其适合那种记录本身尺寸(size)很大的情况,因为此时指针的开销可以忽略不计了 ③删除记录时,比较方便,直接通过指针操作即可

2)缺点: ①存储的记录是随机分布在内存中的,这样在查询记录时,相比结构紧凑的数据类型(比如数组),哈希表的跳转访问会带来额外的时间开销如果所有的 key-value 对是可以提前预知,并之后不会发生变化时(即不允许插入和删除),可以人为创建一个不会产生冲突的完美哈希函数(perfect hash function),此时封闭散列的性能将远高于开放散列 ③由于使用指针,记录不容易进行序列化(serialize)操作

2.封闭散列(closed hashing)/ 开放定址法

优缺点

封闭散列(closed hashing)/ 开放定址法

1)优点: ①记录更容易进行序列化(serialize)操作 ②如果记录总数可以预知,可以创建完美哈希函数,此时处理数据的效率是非常高的

2)缺点: ①存储记录的数目不能超过桶数组的长度,如果超过就需要扩容,而扩容会导致某次操作的时间成本飙升,这在实时或者交互式应用中可能会是一个严重的缺陷
②使用探测序列,有可能其计算的时间成本过高,导致哈希表的处理性能降低 ③由于记录是存放在桶数组中的,而桶数组必然存在空槽,所以当记录本身尺寸(size)很大并且记录总数规模很大时,空槽占用的空间会导致明显的内存浪费 ④删除记录时,比较麻烦。比如需要删除记录a,记录b是在a之后插入桶数组的,但是和记录a有冲突,是通过探测序列再次跳转找到的地址,所以如果直接删除a,a的位置变为空槽,而空槽是查询记录失败的终止条件,这样会导致记录b在a的位置重新插入数据前不可见,所以不能直接删除a,而是设置删除标记。这就需要额外的空间和操作。
另外还有一篇:

(1)拉链法处理冲突简单,且无堆积现象,即非同义词决不会发生冲突,因此平均查找长度较短;
(2)由于拉链法中各链表上的结点空间是动态申请的,故它更适合于造表前无法确定表长的情况;
(3)开放定址法为减少冲突,要求装填因子α较小,故当结点规模较大时会浪费很多空间。而拉链法中可取α≥1,且结点较大时,拉链法中增加的指针域可忽略不计,因此节省空间;
(4)在用拉链法构造的散列表中,删除结点的操作易于实现。只要简单地删去链表上相应的结点即可。而对开放地址法构造的散列表,删除结点不能简单地将被删结点的空间置为空,否则将截断在它之后填人散列表的同义词结点的查找路径。这是因为各种开放地址法中,空地址单元(即开放地址)都是查找失败的条件。因此在用开放地址法处理冲突的散列表上执行删除操作,只能在被删结点上做删除标记,而不能真正删除结点。

附上常见的面试题:
首先是一个总览,从STL中的map和unordered_map

map与unordered_map
相同:两者都是键-值对的集合,关联容器的一种。两者中的元素都是pair,同时拥有实值和键值。两者都不允许有两个相同的键值(实值可以相同)。两个的外部接口调用基本一致。
不同:内部实现机理不同,即map内部实现了一个红黑树;unordered_map内部实现了一个哈希表。(两者的比较成为红黑树与哈希表的比较)。由于内部实现机理不同(底层实现)造成以下不同。
map的有序性:红黑树(非严格平衡二叉树),该结构具有自动排序的功能,因此map内部的所有元素都是有序的。
unordered_map的无序性:哈希表不会根据key值大小进行排序,存储时是根据key的hash值判断元素是否相同,因此unordered_map内部元素是无序的。
map的运行效率:红黑树可以在O(log n)时间内做查找,插入和删除,这里的n是树中元素的数目。
unordered_map的运行效率:哈希表的查找的时间复杂度可达到O(1) unordered_map内存占用比map高。 红黑树
定义:RB-tree是一个需满足以下规则的二叉搜索树 每个结点不是红色就是黑色 根结点为黑色 每个叶结点(空结点)是黑色的
每个红色结点的两个子结点都是黑色的 从任一节点到其每个叶子结点的所有路径都包含相同数目的黑色节点。 为什么红黑树是一种好的搜索树
一棵内部有n个结点的红黑树的高度至多为2∗logn(性质4)。这保证了红黑树任意操作的复杂度都是O(logn)。
基本操作:左旋,右旋,重新着色
目的:红黑树在插入,删除过程中可能会破坏原本的平衡条件导致不满足红黑树的性质,这时候一般情况下要通过左旋、右旋和重新着色这个三个操作来使红黑树重新满足平衡化条件。
左旋 右旋 重新着色 哈希表 定义:散列表(Hash table,也叫哈希表),是根据关键码值(Key
value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。
哈希函数 直接寻址法 数字分析法、 平方取中法 折叠法 随机数法 除留余数法 解决碰撞(冲突): 开放寻址法:Hi=(H(key) +
di) MOD m,i=1,2,…,k(k<=m-1),其中H(key)为散列函数,m为散列表长,di为增量序列(1)线性探测
di=1,2,3,…,m-1;(2)二次探测
di=12,-12,22,-22,⑶2,…,±(k)2,(k<=m/2);(3)伪随机探测 di=伪随机数序列,

再散列法:Hi=RHi(key),i=1,2,…,k
RHi均是不同的散列函数,即在同义词产生地址冲突时计算另一个散列函数地址,直到冲突不再发生,这种方法不易产生“聚集”,但增加了计算时间。
链地址法:如果遇到冲突,会在原地址新建一个空间,然后以链表结点的形式插入到该空间。

查询性能: 散列函数是否均匀

处理冲突的方法

散列表的装填因子 :α= 填入表中的元素个数 / 散列表的长度

1.什么是哈希冲突?

不同关键字通过相同哈希计算出相同的哈希地址,该种现象称为哈希冲突或哈希碰撞。

2.处理哈希冲突的方法有哪些?优缺点分别是什么?

解决哈希冲突两种常见的方法是:闭散列和开散列

3.哈希表的增删查改的时间复杂度是多少?
开放定址法哈希冲突很严重怎么办?
哈希桶哈希冲突很严重怎么办?

查找索引当然会很快,不过只有无冲突的hash table复杂度才是O(1),一般是O(c),c为哈希关键字冲突时查找的平均长度。
开放地址法是当发生冲突时,使用某种探查技术在散列表中形成一个探查序列,按照这个序列逐个单元查找,直到找到合适的位置。线性探测法使得大量元素在相邻地址出现“聚集”现象,降低效率。主要是解决冲突算法选择不好,如果选择平方探测法即二次探测再散列,则可以有效减少堆积问题(难以避免)!
但还有情况;
线性探测法:一次聚集
平方探测法:二次聚集
哈希桶哈希冲突很严重时就退化成了单个单链表。(具体怎么做Mark一下)

这篇文章有介绍的一些有关运算

4.海量数据处理的面试题?

位图,布隆过滤器等等
参见这里

5.unordered_map和map的区别是什么?哪个更好一些?

unordered_map和map类似,都是存储的key-value的值,可以通过key快速索引到value。不同的是unordered_map不会根据key的大小进行排序,

他们在以下的几个方面有区别:

内部实现

内存使用

时间复杂度

内部实现

std::map将元素存储在一个平衡二叉树中,所以元素是有序存储的。

std::unordered_map使用哈希表来存储元素,元素并不是有序存储。

内存使用

unordered_map比ordered_map更占用内存,因为需要额外的内存来存储哈希表。 查找时间复杂度

std::map的查找时间复杂度是O(log n)。

std::unordered_map最佳的查找时间复杂度是O(1),如果哈希函数不是很好的话,最糟糕的复杂度会是O(n)。

什么时候选择map:

当你需要低内存占用率

当你希望序列是有序的

当你需要稳定的表现

什么时候选择unordered_map

当你有一个很好的哈希函数和对内存占用率没有限制时

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

哈希表/哈希冲突及解决方法(较全) 的相关文章

  • git合并多个commit

    git合并多个commit
  • 深度学习资料

    深度学习资料
  • cmake总结

    cmake 用CMakeList txt产生makefile xff0c make 使用makefile编译可执行程序
  • kuangbin连通图专题,Network of Schools (POJ - 1236,tarjan算法求缩点+缩点的入度与出度的运用)

    kuangbin 题意是有N个学校 每个学校可能向几个学校进行数据传输 xff08 单向的 xff09 问 至少需要把一个文件给几个学校可以使给的N个学校都收到文件 再问在加几个通信线路可以使各个学校之间都能直接或间接的传递文件 一个强连通
  • endnote 文献保留前三个作者

    1 问题描述 xff1a endnote使用GBT7714文献格式 xff0c 显示文献的全部作者 2 想要达到的效果 xff1a 最多显示三个作者 3 解决方法 xff1a 还不知道怎么弄 xff0c 看看以后再来补充 xff0c 心情烦
  • RTK_LIB 源码、可执行文件、rtkget、观测文件、星历文件(精密星历、广播星历)、精密钟差文件介绍

    1 RTK LIB开源程序下载 xff1a 点开rtklib链接 xff1a 下载最新版本的可执行文件和程序源码 2 GNSS数据处理需要的文件 2 1 伪距定位 xff1a spp 观测数据 xff08 0 xff09 导航星历 广播星历
  • RTKLIB ppp rtk_post

    1 实时ppp xff1a IGS MGEX数据处理中心的播发的实时轨道钟差产品 xff0c 结合广播星历 xff0c 实现实时定位 2 事后的 xff08 近似实时 xff09 xff1a 下载精密星历 钟差产品 xff0c 结合其他的精
  • 4.使用静态库、动态库,常见问题解决

    使用动态库的流程 xff08 ORBSLAM3实例 xff09 xff1a 在调用动态库或静态库的 cpp文件添加库的头文件 xff08 可以包含路径 xff0c 也可以在cmakelist文件加头文件搜索路径 xff09 span cla
  • vscode查看代码更新历史

    开源代码推出新版本后 xff0c 如何查看代码更改信息 1 首先打开vscode xff0c 点击左侧的插件管理器 xff0c 进入插件面板 xff0c 搜索Git Graph并安装 2 点击下图图标 xff0c 即可进入Git Graph
  • git更新代码

    一 git一般有很多分支 xff0c 我们clone到本地的时候一般都是master分支 xff0c 那么如何切换到其他分支呢 xff1f 主要命令如下 xff1a 1 查看本地分支文件信息 xff0c 确保更新时不产生冲突 span cl
  • linux---硬链接和软链接

    文件系统 磁盘上文件读写存储与查找系统 xff08 管理 xff09 就是文件系统 xff0c 在每一个分区都会存在自己的文件系统 在这里我们有swap交换分区和文件分区 xff0c 我们这里只介绍文件分区 在文件分区都会有上图中的分块管理
  • char类型数组

    字符数组 xff08 一维 二维 xff09 字符数组是数组元素为char类型的一种数组 凡是适合数组的定义和赋值 xff0c 也都适合于字符数组 由于C语言没有提供字符串类型 xff0c 字符串一般用一维字符数组来存放 xff0c 而二维
  • ubuntu18.04 安装腾讯会议

    腾讯会议现在以及上线了Linux版本 xff0c 可以直接在腾讯会议官网下载linux 版本 xff0c 在官网点击免费下载 xff0c 可以直接下载Linux版本 腾讯会议下载链接 选择Linux版本 xff0c x86 64版本 xff
  • 2.树莓派系统备份

    树莓派使用SD卡来装载系统 xff0c 如果SD卡丢失或者损坏 xff0c 那么树莓派上的数据都会丢失 xff0c 所以一定要备份好SD卡 这篇文章可以帮你备份你的树莓派系统 主要内容为备份SD卡 xff0c 制作树莓派系统镜像以及在需要的
  • ic_gvins编译及环境配置问题解决

    RTK VIO松组合 对惯导精度要求较高 1 环境配置和编译 安装依赖项 span class token comment gcc 8 span span class token function sudo span span class
  • EVO画图设置

    一 绘图设置 1 更改背景色和网格 span class token comment 白色网格 span evo config span class token builtin class name set span plot seabor
  • GINS_OB环境配置

    1 程序简介 武大开源GNSS INS松组合IMU预积分有考虑地球自传和不考虑两种形式可以灵活设置GNSS中断时间IMU可以和里程计进行融合 2 环境配置 span class token comment gcc 8 g 43 43 8 s
  • OB_GINS程序框架

    1 程序运行 span class token builtin class name cd span OB GINS span class token comment 编译好的可执行文件 xff1a bin ob gins xff0c 参数
  • KEIL、MDK中关于__LINE__宏 printf 的显示不正确的问题

    span class token operator gt span define span class token function DEBUG span span class token punctuation span log span
  • VINS-回环检测与重定位

    参考博客 pose graph分析1 pose graph分析2 pose graph分析3

随机推荐

  • 源码安装naviagtion,但是出现[move_base-2] process has died 运行错误的解决办法

    今天开始记录ros遇到的问题 安装navigation可以使用两种方法 第一种 xff1a sudo apt get install ros kinetic navigation 这种安装方法最简单 xff0c 新手或者不需要动naviag
  • linux---静态库和动态库的制作和使用

    静态链接和动态链接 静态链接 xff1a 生成可执行代码 xff0c 链接静态库 xff08 与代码位置有关的链接方式 xff09 xff0c 需要将代码拷贝到我们的源代码中才能运行 动态链接 xff1a 生成可执行代码 xff0c 链接动
  • 加一

    加一 描述 给定一个由整数组成的非空数组所表示的非负整数 xff0c 在该数的基础上加一 最高位数字存放在数组的首位 xff0c 数组中每个元素只存储单个数字 你可以假设除了整数 0 之外 xff0c 这个整数不会以零开头 示例 1 输入
  • STM32bootloader原理解释

    STM32bootloader原理解释 一 STM32的常规启动流程 STM32的内部flash地址起始于0x8000000 xff0c 一般情况下 xff0c 程序文件就从此地址开始写入 此外STM32是基于Cortex M3内核的微控制
  • 模糊PID基本原理及matlab仿真实现(新手!新手!新手!)

    有关模糊pid的相关知识就把自己从刚接触到仿真出结果看到的大部分资料总结一下 xff0c 以及一些自己的ps 以下未说明的都为转载内容 1 转自 https blog csdn net weixin 36340979 article det
  • VMware+ubuntu+win10笔记本实现笔记本连接WIFI且ubuntu既可以上网又能连接开发板

    背景 最近在学习imx6ull开发板的时候 xff0c 发现开发板通过网线连接笔记本电脑却无法ping通ubuntu xff0c 于是捣鼓了很久终于可以了 xff0c 却又发现ubuntu不能上网了 xff0c 经过一番查找资料和尝试 xf
  • 在windows上用vscode打造比vc++6.0好用的C/C++ IDE,适用编程小白

    准备 xff1a 1 安装MinGW xff0c 添加gcc gdb等编译调试工具bin目录 头文件Include目录 库lib的路径到系统环境变量 xff0c 安装LLVM 添 加Clang编译器所在bin目录到系统环境变量 具体操作百度
  • C语言数据结构——线性表的链式存储结构

    文章目录 线性表的链式存储结构1 基本概念2 设计与实现3 优点和缺点 线性表的链式存储结构 1 基本概念 链式存储定义 xff1a 为了表示每个数据元素与其直接后继元素之间的逻辑关系 xff0c 每个元素除了存储本身的信息之外 xff0c
  • 智能车浅谈——硬件篇

    目录 初识小车硬件系统1 电源系统线性电源开关电源 2 人机交互系统3 MCU最小系统4 传感器系统摄像头电感编码器 5 驱动系统 机械结构 17届完赛代码智能车系列文章汇总 前言 xff1a 作为一名老三本玩家 xff0c 笔者深知一些同
  • 智能车浅谈——图像篇

    文章目录 前言认识图像基本含义图像类型数字图像彩色图像灰度图像黑白图像 小结 图像处理图像压缩二值化固定阈值法大津法 图像降噪 xff08 腐蚀 xff09 寻边线 总结17届完赛代码17届完赛代码智能车系列文章汇总 前言 前面已经记录了智
  • 智能车浅谈——手把手让车跑起来(电磁篇)

    文章目录 前言材料准备备赛组车模硬件 练习组车模硬件方案 整车原理赛道信息获取及转向原理工字电感运放模块转向原理元素判断 电机及舵机控制原理 代码实现效果欣赏总结17届完赛代码智能车系列文章汇总 前言 电磁寻迹小车 之前智能车系列已经做了一
  • 手把手教你OneNET数据可视化

    文章目录 前言OneNET实现数据可视化效果一览发布项目 xff08 5 17更新 xff09 总结 前言 之前介绍了Hi3861使用MQTT协议接入OneNET实现数据的上传以及命令的下发 xff0c 本文主要是介绍一下如何使用OneNE
  • linux---进程间通信(ipc)之管道

    进程间通信方式 管道共享内存消息队列信号量本地套接字等等都能作为我们进程间通信的方法 操作系统提供进程间通信方式的原因 因为对于我们进程来说 xff0c 每一个进程都是相互独立的 xff0c 具有独立性 xff0c 如果我们需要两个不同的进
  • 嵌入式学习笔记——STM32的USART收发字符串及串口中断

    USART收发字符串及串口中断 前言字符串的收发发送一个字符串接收字符串需求 利用串口实现printf 中断中断是什么串口的接收中断以及空闲中断实现代码实现效果 总结M4系列目录 前言 上一篇中 xff0c 介绍了串口收发相关的寄存器 xf
  • 嵌入式学习笔记——PWM与输入捕获(下)

    输入捕获 前言输入捕获的概述框图输入通道部分比较捕获寄存器与事件生成 寄存器编程思路 实际需求配置流程打开对应的时钟配置GPIO为复用模式定时器的时基部分配置定时器输入通道部分配置定时器中断配置 代码 xff1a 运行效果 xff1a 需求
  • 嵌入式学习笔记——SPI通信的应用

    SPI通信的应用 前言屏幕分类1 3OLED概述驱动芯片框图原理图通信时序显示的方式页地址 列地址初始化指令 程序设计初始化代码初始化写数据与写命令清屏函数 初始化代码字符显示函数 总结M4系列目录 前言 上一篇中介绍了STM32的SPI通
  • 嵌入式学习笔记——IIC通信

    IIC通信 前言IIC概述通信特征物理拓扑结构IIC通信的流程IIC的特点 xff1a STM32的IIC通信GPIO模拟IICIIC的时序组成 xff08 主机对从机写入数据 xff09 1 起始信号2 器件地址与读写位3 从机应答信号5
  • 立创梁山派学习笔记——GPIO输出控制

    梁山派 前言开发板简介GD32F407ZGT6官方资源数据手册1 系统框图2 引脚复用表3 命名规则4 其他 用户手册固件库与PACK包 开发环境搭建立创官方的资料包资料齐活 xff0c 开发1 工程搭建2 使用寄存器点亮LEDGPIO数量
  • C51_day5:串口通信UART

    3 1 串口基本认知 串行接口简称串口 xff0c 也称串行通信接口或串行通讯接口 xff08 通常指COM接口 xff09 xff0c 是采用串行通信方式的扩展接口 串行接口 xff08 Serial Interface xff09 是指
  • 哈希表/哈希冲突及解决方法(较全)

    哈希表的概念请参阅他人文章 xff0c 关于哈希冲突的解决这篇文章基本都整理到了 xff0c 还有几个常见的面试题 解决hash冲突的几种方法 前导 xff08 题外话 xff09 xff1a 一 开放定址法 xff08 闭散列 xff09