C语言学习相关
函数递归
函数递归,简单的理解就是,自己调用自己,直到遇到边界条件,停止递归
比如我们想实现一个阶乘函数
12345678910111213141516171819202122232425262728int n = 5;//求n! 这里是5!//不使用递归,一种可行的做法是这样int ans = 1;for (int i = 1; i <= n; i++) { ans *= i;}printf("%d! = %d", n, ans);//使用递归int _n(int x) { if (x == 0)return 1; return x * _n(x - 1);}printf("%d! = %d", n, _n(n));/*对于 _n(5),我们拆分一下它自己调用自己的过程↓_n(5) 5 * _n(4) 4 * _n(3) 3 * _n(2) 2 * _n(1) 1 * _n(0) 1达到边界,返回值为:5*4*3*2*1*1的 结果 (是,结果,不是 ...
STM32阵列按键
阵列按键
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182uint8_t Key_GetNum(void) { uint8_t keyNum = 0; /* 在Key_init()中 设置所有行为高电平,列为输入下拉模式(IPD) GPIO_SetBits(GPIOB, Key_ROW1 | Key_ROW2 | Key_ROW3 | Key_ROW4); GPIO_ResetBits(GPIOA, Key_Pin_A_All); GPIO_ResetBits(GPIOC, Key_Pin_C_All); */ GPIO_SetBits(GPIOB, Key_ROW4); GPIO_ResetBits(GPIOB, Key_ROW1); if (GP ...
CH32(F10X F20X)
对于WCH-link的接线
F103
1234567U -> 板上SWD区域Rx -> PA9(Tx)Tx -> PA10(Rx)GND -> GND3V3 -> VCCSWDIO-> PA13SWDLK-> PA14
F207
1234567U -> 板上SWD区域Rx -> TXDTx -> RXDGND -> GND3V3 -> VDDSWDIO -> SWIOSWDLK -> SWCK
对于096 OLED屏幕接线
F207
GND 电源地
VCC 电源正(3.3~5V)
D0(SCL) SCK管脚
D1(SDA) MOSI管脚
RES(RST) 用来复位(低电平复位)
DC(D/C) 数据和命令控制管脚 1表示数据 0表示命令
CS(NSS) 片选管脚
1234567GND -> GNDVCC -> 3V3D0 -> PA5D1 -> PA7RES -> PA4DC -> PA6CS -> NONE
最短路
最短的求解一般会遇到多种情况
有向无环图
权值为正
权值有负
有向有环图
权值为正
权值有负
负权边和负权环 Bellmon-Ford
权值非负的有向或无向图 Dijkstra
Dijkstra
Dijkstra本质上是一种贪心算法,通过不断调整每个点的“当前距离”最终得到最优结果
这种不断调整的过程,维基百科上面称为**“relax"(松弛)**
算法流程
对于求一点s到其他所有点的最短距离
对于每个点v均维护一个当前距离(dis[v])和 是否访问过(vis[v])。首先将dis[s]初始化为无穷,所有点访问状态(vis)置为未访问
对于一条边u->v,其边权为weight[u->v],我们存储在了v.first中(v为G[u]中的一个邻接点)
从所有未访问的点中,找出当前距离最小的,设为u,并将其标记为已访问的。
调整u的所有边(若是有向图则为出边)连接的并且未被访问过的点:
若weight[u->v] + dis[u] < dis[v], 则将dis[v]更新为dis[u]+weight[u->v],体现 ...
拓扑排序
什么是拓扑排序?
在图论中,拓扑排序(Topological Sorting)是一个有向无环图(DAG, Directed Acyclic Graph)的所有顶点的线性序列。且该序列必须满足下面两个条件:
每个顶点出现且只出现一次
若存在一条从顶点 A 到顶点 B 的路径,那么在序列中顶点 A 出现在顶点 B 的前面
有向无环图(DAG)才有拓扑排序,非DAG图没有拓扑排序一说
拓扑排序有什么用?
它可以用来解决形如:
有n个任务需要完成,每个任务有一个耗时和一个前置任务列表,前置任务完成后才能开始当前任务。求完成所有任务的最短时间
这样具有依赖关系的问题
拓扑排序的实现
实现拓扑排序的关键就是维护一个入度为0的顶点的集合
Eg:P1113 杂务
题目描述
John的农场在给奶牛挤奶前有很多杂务要完成,每一项杂务都需要一定的时间来完成它。比如:他们要将奶牛集合起来,将他们赶进牛棚,为奶牛清洗乳房以及一些其它工作。尽早将所有杂务完成是必要的,因为这样才有更多时间挤出更多的牛奶。当然,有些杂务必须在另一些杂务完成的情况下才能进行。比如:只有将奶牛赶进牛棚才能开始为它清洗乳房,还有 ...
图的表示
邻接矩阵实现
12345678910111213141516171819#define MAXN 10001int G[MAXN][MAXN], Nv, Ne;void BuildG() { int u, v, w; cin >> Nv; /*CreateGraph*/ for (int i = 0; i < Nv; i++) { for (int j = 0; j < Nv; j++) { G[i][j] = 0; } } cin >> Ne; for (int i = 0; i < Ne; i++) { cin >> u >> v >> w; /*InsertEdge*/ G[u][v] = w; G[v][u] = w;//针对无向图,双向建边 }}
AutoCAD
[TOC]
CAD是先设置相关样式,后绘制
命令
MENUBAR(菜单模式)
0 非标准菜单模式
1 标准菜单模式
GRID(辅助栅格)
显示/不显示
开(ON) 关(OFF) 捕捉(S) 主(M) 自适应(D) 界限(L) 跟随(F) 纵横向间距(A)
OP(界面设置)
界面设置
再次按下回车可以重复运行上次的指令
CTRL+o(全屏)
QS(快速保存)
LA(图层命令)
图层命令
Z(缩放)
绘制相关
L(直线) PL(多段线)
> 注意 **相对坐标**
REC(矩形)
> 参数:
>
> E (完全显示)
LW(线宽)
SPL(曲线)
完成闭合曲线后,输入c(闭合)
X
将一条线段分为两条
O(偏移命令)
按键后输入偏移值
U
U == ctrl+z
TR(修剪)
按键后按T,选择剪切边,回车,再次选择,被选择线与剪切边间的线将被剪切
CO(copy)
选完后回车
选择基准点,选完后要求选新的基准点
文字相关
MT(多行文字)
DT(单行文字)
ST(文字样式)
DDEDIT(文字编辑)
B(块定义)
BED ...
二叉搜索树(BST)
[TOC]
性质
二叉搜索树本质上还是一棵二叉树,其满足以下性质(习惯性定义为):
非空左子树的所有键值小于其根结点的键值
非空右子树的所有键值大于其根结点的键值
左右子树都是二叉搜索树
基本函数
1234567891011121314//从二叉搜索树BST中查找x,返回结点地址Poi Find(ElementType x, BinTree BST);//从二叉搜索树BST中查找最小元素的结点地址Poi FindMin(BinTree BST);//从二叉搜索树BST中查找最大元素结点地址Poi FindMax(BinTree BST);//向二叉搜索树BST插入值为x的结点BinTree Insert(ElementType x, BinTree BST);//向二叉搜索树BST删除值为x的结点BinTree Delete(ElementType x, BinTree BST);
Find
12345678910111213BiNode* BiSearchTree::Find(int x, BiNode* BST){ if (!BST) return nullptr; ...
二叉树的遍历序列转换
前序中序转后序
输入#1
12ABEDFCHGCBADEFGH
输出#1
1AEFDBHGC
针对二叉树的
前序遍历,根->左->右
中序遍历,左->根->右
这两个的特性
我们可以尝试凭借前序遍历的根结点(叶子结点也可以看错左右儿子为空的根)将中序遍历的左右根依次拆分成左右两块,针对左右两块再次递归操作
12345678910111213141516171819void _find(string InOrderStr, string PreOrderStr){ if (PreOrderStr.empty())return;//针对前序遍历序列(拆分出的序列的)的根结点访问结束 char root = PreOrderStr[0]; PreOrderStr.erase(PreOrderStr.begin());//根结点取出,作为拆分标识 int rootidx = InOrderStr.find(root); string leftIn = InOrderStr.substr(0,rootidx); ...
二叉树的遍历
先序遍历
根->左子树->右子树
1234567void BiTree::PreOrder(BiNode* B) { if (B) { cout << B->data << endl; PreOrder(B->left); PreOrder(B->right); }}
中序遍历
左子树->根->右子树
1234567void BiTree::InOrder(BiNode* B) { if (B) { PreOrder(B->left); cout << B->data << endl; PreOrder(B->right); }}
后序遍历
左子树->右子树->根
1234567void BiTree::PostOrder(BiNode* B) { if (B) { PreOrder(B->left); PreOrder(B->r ...