- 博客(50)
- 收藏
- 关注
原创 力扣题解106:从中序与后序遍历序列构造二叉树
本文介绍如何根据二叉树的中序和后序遍历序列重建原二叉树。通过递归方法,利用后序序列的末位元素确定根节点,在中序序列中找到左右子树分界点。算法步骤包括:1)判断空树情况;2)提取根节点;3)划分左右子树;4)递归构建子树。C++实现中,traversal函数处理子树划分和递归构建,buildTree函数作为入口。时间复杂度为O(n),需遍历节点定位根位置。该方法有效解决了二叉树重建问题,关键点在于准确划分遍历序列的左右子树范围。
2025-06-01 10:53:06
479
原创 leetcode题解513:找树左下角的值(递归中的回溯处理)!
题目要求找到二叉树最底层最左边节点的值。采用深度优先搜索(DFS)方法,通过递归遍历整棵树,记录当前深度和最大深度。当遇到叶子节点时,若当前深度大于最大深度,则更新结果值和最大深度。遍历时优先访问左子树,确保找到同一深度层的最左节点。在递归回溯时需手动调整深度参数。算法时间复杂度为O(n),空间复杂度为O(h),其中n为节点数,h为树高。该方法通过一次遍历即可准确锁定目标节点,兼顾效率与准确性。
2025-05-30 14:31:50
628
原创 让你的STM32变身简易示波器,学会输入捕获就可以!
本文介绍了STM32微控制器输入捕获(Input Capture)功能在PWM信号测量中的应用。通过配置定时器的输入捕获单元,可以精确测量外部信号的频率和占空比。文章详细讲解了测频法和测周法的原理,并提供了完整的代码实现方案,包括初始化定时器、GPIO配置、捕获模式设置等关键步骤。代码展示了如何在STM32F103平台上通过TIM3定时器捕获PWM信号参数,并将结果实时显示在OLED屏幕上。该方案适用于需要精确测量外部信号参数的嵌入式应用场景。
2025-05-29 11:41:27
254
原创 新手项目必备技能:PWM驱动电机、舵机、呼吸灯
PWM是一种通过改变脉冲信号的宽度来控制设备的技术。PWM信号由高电平和低电平组成,通过调整高电平的持续时间(脉冲宽度),可以实现对设备的精确控制。PWM信号的两个重要参数是占空比和频率占空比:高电平时间与整个周期时间的比值,通常用百分比表示。频率:PWM信号的周期性重复速率,单位是赫兹(Hz)。时基单元PSC(预分频器):用来降低计数器的计数速度。比如,如果输入时钟是1MHz,预分频器设置为1000,那么计数器的计数速度就变成了1kHz。
2025-05-28 16:35:27
932
原创 想要掌握STM32定时器中断?这一篇文章就够了
本文介绍了STM32外部定时器中断的基本原理与应用。定时器通过对时钟信号计数实现精准定时,支持多种工作模式如向上计数、PWM输出等。文章详细讲解了TIM2定时器的初始化代码配置,包括GPIO设置、时钟源选择、时基单元配置及NVIC中断优先级设置。通过实例代码展示了如何使用定时器中断实现计数值累加,并配合OLED显示实时计数状态。中断服务函数中实现计数值更新和标志位清除,主循环则持续显示当前计数值。该实例可作为STM32定时器中断应用的入门参考。
2025-05-27 16:22:27
808
原创 初学STM32外部中断?小白看这篇就够了!
摘要:嵌入式系统中,外部中断(EXTI)是中断机制的重要类型,由外部信号触发。STM32配置外部中断需执行5个步骤:1)GPIO引脚设为输入模式;2)EXTI控制器设置触发条件;3)SYSCFG/AFIO模块引脚映射;4)NVIC使能中断并设优先级;5)编写中断服务函数(ISR)。代码示例展示了TIM2定时器和GPIOA的配置过程,包括时钟使能、引脚模式设置、NVIC优先级分组等关键操作,实现外部中断触发定时器计数的功能。
2025-05-26 11:22:42
867
原创 leetcode题解:144+145 二叉树的前序、后序遍历(非递归!)
本文介绍了二叉树前序和后序遍历的非递归实现方法。前序遍历利用栈结构,先将根节点入栈,然后依次处理右、左子节点,确保"根-左-右"顺序。后序遍历采用"伪前序+反转"技巧,先按"根-右-左"顺序遍历,最后反转结果得到"左-右-根"的正确顺序。文中提供了详细的C语言实现代码,包括栈结构定义、基础操作函数以及两种遍历算法实现。算法时间复杂度为O(n),空间复杂度为O(h)。关键技巧包括:前序遍历要注意入栈顺序,后序遍历通过反转简化实现。
2025-05-25 13:33:58
291
原创 STL 标准模板库全面解析:容器、算法与迭代器的核心应用
STL(标准模板库)是C++的核心库,提供六大组件:容器(vector、list等)、算法(sort、find等)、迭代器、仿函数、适配器和空间配置器。容器分为序列式(如vector、deque)和关联式(如set、map),通过迭代器连接算法。STL支持泛型编程,提升代码复用性,但需注意迭代器失效问题(如vector扩容时)。性能优化技巧包括预留空间、选择合适容器等。STL广泛应用于数据结构与算法实现,是C++开发的重要工具。
2025-05-25 13:26:35
792
原创 STM32 的 GPIO 多种输入输出模式分不清?本文一站式搞懂!
STM32的GPIO(通用输入输出端口)是连接芯片与外部设备的核心接口,支持多种输入输出模式。输入模式包括浮空、上拉、下拉和模拟输入,分别适用于不同电平检测和模拟信号采集场景。输出模式包含推挽、开漏及复用模式,可用于驱动LED、I2C通信等应用。使用GPIO需先启用时钟,再配置模式(如推挽输出控制LED),最后通过置位/复位引脚控制设备。合理选择GPIO模式能提升系统稳定性和可靠性。
2025-05-25 13:09:15
804
原创 数据库中表的设计规范
数据库表结构主要由列、行、主键和外键构成,其中列存储单一数据项,行是唯一记录。主键分为业务主键和代理主键,用于唯一标识记录;外键则用于表间关联。关系范式(1NF-3NF)通过约束确保表结构设计合理:1NF要求字段不可再分;2NF要求非主键字段完全依赖主键;3NF消除非主键间的传递依赖。规范化设计能减少冗余、保证数据一致性、简化维护并提高查询效率,但在特定场景下可能采用反范式优化性能。
2025-05-24 19:33:30
379
原创 进阶!归并排序代码实现(C语言)
归并排序是一种采用分治策略的高效排序算法。其核心思想是将数组递归分解为最小单元后有序合并,C语言实现需注意分解、合并和递归调用三个关键环节。算法时间复杂度稳定为O(nlogn),但需要O(n)额外空间。具体步骤包括:分解数组至单个元素、合并两个有序子数组、递归完成整体排序。代码实现展示了分块归并的过程,通过交替使用辅助数组完成排序,最终确保结果存储在原始数组中。该算法性能优越,适合大规模数据排序。
2025-05-22 11:52:57
298
原创 校招面试必考!快速排序(C语言)
快速排序是一种高效的分治排序算法,通过选择基准值将数组划分为左右两部分并递归排序。C语言实现要点包括基准值选择(如三数取中法)、分区操作和递归处理。时间复杂度平均为O(nlogn),最坏情况O(n²)可通过优化避免。具体步骤为:1)选择基准值;2)分区操作交换元素;3)递归排序子数组。文末给出了完整的快速排序C语言实现代码。
2025-05-22 11:23:33
284
原创 几种排序方式的C语言实现(冒泡、选择、插入、希尔等)
定义两个指针, Left Right 左指针右移找到比基准大的数, 右指针左移找到比基准小的数,两个指针交换内容,假设未排序的第一个为最小值,然后遍历未排序的内容,找到真正的最小值,和未排序的第一个位置互换,相邻两个元素比较,若前面一个元素大,就交换位置,一轮进行n-1次比较,一共执行n-1轮。基准:第一个或者最后一个元素, 优化方案:第一个、最后一个,中间元素 ,三个数的中间值。- 其他排序:冒泡、选择、插入、快速、归并、希尔、堆……- OO(n*n):冒泡、选择、插入、希尔...然后十位、百位、、、
2025-05-16 19:19:06
223
原创 C++ 核心知识全面解析:从基础语法到面向对象与 STL
这是因为成员函数的第一个参数是隐式的 this 指针,它指向调用该函数的对象(必须是类类型)。如果类的变量开辟在堆区,然后再用赋值操作,P1=P2则P2的变量和P1的变量指向同一块堆区内存,在析构时就会对同一区域释放两次,造成程序崩溃。,但前向声明只告诉编译器 GoodGay 是一个类,而不会提供其成员函数的声明。这段代码打印时,只有第一次可以正常打印,因为局部变量在释放时,编译器会保留一次,但是第二次就不再保留了。当其他类的对象作为本类成员,构造时,先构造本类的对象,再构造自身, 先构造A,再构造B。
2025-05-10 10:23:01
357
原创 力扣题解:2、两数相加
个人认为,该题目可以看作合并两个链表的变种题,本题与21题不同的是,再处理两个结点时,对比的不是两者的大小,而是两者和是否大于10,加法计算中大于10要进位,所以我们需要声明一个用来标记是否进位的值。3、每次相加后,可能会有进位(即和大于等于10),需要将进位加到下一位的计算中。5、如果遍历完所有节点后仍有进位,需要额外创建一个节点来存储这个进位。2、同时遍历两个链表,将对应位置的数字相加,并考虑前一位的进位。4、如果两个链表长度不同,较短的链表在后续遍历中可以视为。
2025-05-10 10:19:55
370
原创 C++演讲比赛案例代码
speechmanager.h : 存放功能函数的声明,以及speaker的容器。该案例是黑马的案例,不方便下载源代码的可以看一下。speaker.h :里面存放speeker类。speechmanager.c :功能函数的实现。main.c :与用户交互 ,显示菜单等。该案例有两个头文件,两个源文件。第一轮演讲12人,用v1存储。胜出的3人,用win存储。第二轮6人,用v2存储。
2025-05-05 11:10:39
364
原创 哈希表的线性探测C语言实现
哈希表(Hash Table)是一种基于哈希函数实现的高效数据结构,用于存储键值对(Key-Value)。它通过哈希函数将键(Key)映射到一个较小范围的整数值(通常是数组的索引),从而快速定位存储位置。哈希表的核心在于通过哈希函数实现快速的插入、查找和删除操作,其平均时间复杂度接近。
2025-04-26 14:37:00
687
原创 C语言数据结构:树的实现、前序、中序、后序遍历
树是一种非线性的数据结构,由若干个节点组成。每个节点都包含数据,并且可以有多个子节点。树的最顶端是一个特殊的节点,叫根节点,它没有父节点。从根节点开始,树不断向下分叉,形成不同的层次。最底层的节点叫叶子节点,它们没有子节点。
2025-04-12 18:50:48
467
原创 力扣题解:142. 环形链表 II
循环链表是一种特殊类型的链表,其尾节点的指针指向头节点,形成一个闭环。4).快指针在一圈内追上慢指针:如果慢指针走一圈,快指针则走了两圈,在这两圈内,快指针一定会与慢指针相遇,所以快指针在一圈内追上慢指针。2).如果有环,则快指针先进入环,慢指针后进入环, 如果无环,则fast会走出循环判断条件,返回空。3).有环时,慢指针进入环后,快指针相对慢指针每次移动一格,也就是快指针会追上慢指针。1).我们声明两个指针,快指针每次向链表下方走两步,慢指针则走一步;入口距离=(n-1)圈长+相遇点到入口的距离。
2025-04-09 21:41:33
383
原创 C语言数据结构:队列的操作实现
队列是一种常见的数据结构,遵循先进先出(FIFO)原则,即最先进入的元素最先被移除。它类似于现实生活中的排队,先到的人先接受服务。
2025-03-28 20:55:33
284
原创 C语言数据结构:栈的操作实现
2、进制转换(直接取余得到的顺序和结果相反,通过栈来调转)本文使用顺序栈,实现二进制转换。1、中缀表达式转后缀表达式。栈(Stack)是一种遵循。3、款项金额转中文大写。4、编辑器中括号的匹配。
2025-03-21 20:34:51
234
原创 C语言数据结构:双向链表的操作实现
双向链表(Doubly Linked List)是一种常见的线性数据结构。与单链表不同,双向链表的每个节点不仅包含指向下一个节点的指针(对双向链表的操作有:头插法,尾插法,清空链表,遍历链表,得到尾结点,特定位置插入,特定位置删除。这种结构使得双向链表可以从两个方向遍历,操作更加灵活。:由于有前驱指针,可以更方便地操作节点的前驱和后继。接下来我们通过代码来看对双向链表的操作。),还包含一个指向前一个节点的指针(:每个节点需要额外存储一个前驱指针。:可以从头到尾或从尾到头遍历链表。
2025-03-15 15:27:05
148
原创 C语言数据结构:链表的操作实现
2、寻找链表的中点(也可以找到其他比例的点去分割链表):快指针一次向尾部走两步,慢指针走一步,直到指向NULL,这时慢指针就会指向中间结点(偶数链表会指向中间的上一个,奇数会指向中间值)。本文包括链表的基本操作:初始化、头插法、尾插法、遍历打印、获取尾结点地址、指定位置添加和删除结点、获取链表长度、得到尾指针、释放链表、获得倒数第K个结点的值(快慢指针法)、翻转链表。1.找到倒数第K个值:快指针先走K步,循环向链表尾部走,直到指向NULL,这时慢指针就会指向想要的结点。
2025-03-09 17:02:50
380
原创 数据结构笔记
O(1)<O(log2n)(以2为底)<O(n)<O(nlog2n)<O(n²)<O(n³)<O(2^n)<O(n!数据:所有能够输入到计算机中,且能被计算机处理的符号的集合。- 链式存储 (每个节点、数据元素 附加额外的指针字段,通过指针建立逻辑关系)数据(集合)中的一个个体,是数据的基本单位,包含多个数据项。数据元素在存储器(内存、磁盘)中的存储结构 ,面向开发者。T(n) = O(f(n)),使用 O() 表示,<A,B> A是B的前驱,B是A的后驱。数据对象:由属性相同的数据元素构成的集合。
2025-03-09 16:22:57
242
原创 c语言数据结构:顺序表增删改查函数的实现
1、下列代码中 我用Eelemtype 来对int 取别名,在本段代码中意义不明显,但是在大量数据中如果要改int 型为 double型,则取别名的有点就显现出来了。其中共包含:1、初始化 2、最后一位插入 3、遍历 4、特定位置插入数据元素 5、特定位置删除数据元素 6、查找数据元素e第一次出现的位置。在数据结构中,我们最先接触到的内容就是线性表,本片文章的内容就是线性表中对顺序表增删改查的c语言实现。5、要注意顺序表的位置和在数组中序号的关系,length-1。4、对结构体取别名 Sq。
2025-03-06 18:04:34
302
原创 C语言学习笔记:初阶指针
在上述结果中我们可以看到,指针是有自己的地址的,当我们把指针指向a数组后,打印指针内的内容就变成了数组的首地址,我们通过 * 解引用,可以取出数组首地址中所存储的内容。我们需要对 * 解引用符号和& 取地址符号保持敏感,当指针名前有解引用符号,则表示的是指针里内容的地址,,当指针名前有&取地址时,则表示指针本身的地址。与系统有关 32位 4字节 64位 8字节,指针使用前需要赋值 , 否则就是空指针。在以后对指针的运用中,我们很容易搞混指针地址,指针中的地址,指针中的地址里的内容。
2025-03-06 17:45:09
162
原创 C语言学习笔记:函数的递归
首先我们声明了两个函数 func1 和 func2 分别采用不同的方法,func1 返回一个整型变量,我们直接赋值为6,省略判断步骤,func1需要一个for循环来解决这个计算,而func2,他的返回值是一个三元运算,只需要一行就可以完成计算需求。观察func2就可以发现,在将3赋值给n时,会进行第一次三元运算,判断 n是否大于1,n=3,则n*func2(n-1),这时再次调用func2函数,形参就变成了2,然后再次判断后进入三元运算,这时n=1,返回值为3*2。函数是构成c语言的基本单元;
2025-02-18 15:18:34
461
原创 C语言学习笔记:子函数的调用实现各个位的累加和
然后 n除以10 ,然后判断n是否符合条件,如果n>0 ,则再次将n对10取余,将得到的数加到r,往复此步骤,直到n<0,然后返回 r ,得到各个位的累加和。首先我们先思考以下各个位的和怎么计算:举例,483,我们首先求他的个位数,则是483%10,对10取余,得到3,然后求他的十位数,483/10=48(因为我们用的整数计算,没有用浮点数,所以对省略小数部分),48%10=8,再次对10取余得到8,那么我们再除以十,得到4,4%10=4,然后我们将3 8 4累加起来,就是我们想要的结果。
2025-02-10 14:52:02
382
1
原创 C语言学习笔记:while循环实现2进制转换
在这个代码内,我们首先声明了整型变量n,这代表我们输入的数,i 则是计数器,因为我们让n/2后的余数存储到数组内,就需要一个计数器来作为索引,即第一次循环结果存储到a[0],第二个存储到a[1]……然后我们声明数组,因为我们数组的大小是根据循环次数来定义的,所以我们没办法直接初始化,但是当输入 0和1时都有不进入循环的情况,所以数组内有垃圾值,我们需要进行初始化。在进行转换时,先让输入的十进制数对2取余,这个值存入到数组内,然后让输入值除以2,再次进行循环,直到输入的数为0。
2025-01-25 21:19:31
352
1
原创 C语言学习笔记:for循环和打印等腰三角形(*)
我们先看变量为 J 的循环,我们需要在这个循环内解决每行打印几个的问题,我们先思考第一行,如果我们输入的c = 3,则最下面一行有5个 * 第二行则有 3个 * 号 ,第一行有1个 * 号,我们可以看出 如果是c = 4,从下到上则是7、5、3、1。我们可以思考出第一行的打印位置是当j = c时打印,第二行打印的3个则是再 c位置的左右两侧 1位,第三行则是 c位置的左右两侧两位,以此类推我们可以知道:;打印终点位置:c+行数-1,打印第二行时,i=1,在c-1到c+1的三个位置上打印*
2025-01-20 18:17:45
668
1
原创 C语言学习笔记:位运算和三元运算
在计算机中的数大多都是以二进制进行存储的,位运算就是对二进制数位进行操作的运算,这样可以大大提升运算效率,也更方便理解。在位运算中有与、或、异或、取反、左移、右移6个运算符,如图有运算规则。在此介绍一下异或的一种用法:可以通过异或运算进行两个数值的交换。#异或 ^ 运算两者不同 有真为真 1相同的值异或得 0a=2 b=3 互换位置1011――01 a=a^b0111――10 b=a^b0110――11 a=a^b。
2025-01-15 20:02:33
185
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人