7-1.将图以邻接矩阵存储,实现DFS。

code

#include<bits/stdc++.h>
using namespace std;
int book[100], sum, n, e[100][100];void dfs(int cur){printf("%d ", cur);sum++;if (sum == n)return;for (int i = 1; i <= n; i++){if (e[cur][i] == 1 && book[i] == 0){book[i] = 1;dfs(i);}}return;
}int main(){int i, j, m, a, b;printf("请输入顶点数和边数:\n");scanf("%d%d", &n, &m);for (i = 1; i <= n; i++)for (j = 1; j <= n; j++)if (i == j)e[i][j] = 0;elsee[i][j] = 99999;//假设99999为无穷大;for (i = 0; i < m; i++){printf("请输入第%d条边:\n", i + 1);scanf("%d%d", &a, &b);e[a][b] = 1;e[b][a] = 1;}book[1] = 1;printf("深度优先遍历结果为:");dfs(1);return 0;
}

运行截图

7-2.将图以邻接表存储,实现BFS。

code

#include<bits/stdc++.h>
using namespace std;//边表节点结构,一个adjvex用来存储邻接点的位置,一个next指针用来指向下一个节点
typedef struct EdgeNode
{int adjvex;struct EdgeNode * next;
} EdgeNode;//顶点表节点结构,一个data用来存储数据,一个firstedge是用来指向边表的第一个节点
typedef struct
{string data;EdgeNode * firstedge;
} AdjList;//里面的adjList[15]表示我给顶点表开了15的单位大小,然后numVertex,numEdge是一个图的顶点数和边数
typedef struct
{AdjList adjList[15];int numVertex,numEdge;
} GraphAdjList;
//这个函数是这样的,它会遍历图的顶点,然后返回一个位置(其实也就是它所在的下标)
int local(GraphAdjList G,string val)
{for(int i=0; i<G.numVertex; i++){if(G.adjList[i].data==val)return i;}return -1;
}
//比如v2的位置是在2 这个可以看上面的顶点表图
void CreateGraph(GraphAdjList & G)
{int i,j,k;string v1,v2;EdgeNode * e,* p,*q;cout<<"请输入顶点数和边数,并以空格隔开:"<<endl;cin>>G.numVertex>>G.numEdge;cout<<"请输入顶点的信息:"<<endl;for(i=0; i<(G.numVertex); i++){//cout<<"第"<<i+1<<"个顶点:"<<endl;cin>>G.adjList[i].data;G.adjList[i].firstedge=NULL;}for(k=0; k<(G.numEdge); k++){//cout<<"请输入边(Vi,Vj)上的顶点信息:"<<endl;cin>>v1>>v2;i=local(G,v1);j=local(G,v2);if(G.adjList[i].firstedge==NULL){e= new EdgeNode;e->adjvex=j;e->next=NULL;G.adjList[i].firstedge=e;}else{p=G.adjList[i].firstedge;while(p->next!=NULL){p=p->next;}e = new EdgeNode;e->adjvex=j;e->next=NULL;p->next=e;}if(G.adjList[j].firstedge==NULL){e= new EdgeNode;e->adjvex=i;e->next=NULL;G.adjList[j].firstedge=e;}else{p=G.adjList[j].firstedge;while(p->next!=NULL){p=p->next;}e = new EdgeNode;e->adjvex=i;e->next=NULL;p->next=e;}}
}
void Prin(GraphAdjList G)
{cout<<"所建立的邻接表如以下所示:"<<endl;for(int i=0; i<G.numVertex; i++){cout<<G.adjList[i].data;             //先输出顶点信息EdgeNode * e = G.adjList[i].firstedge;while(e)                              //然后就开始遍历输出每个边表所存储的邻接点的下标{cout<<"-->"<<e->adjvex;e=e->next;}cout<<endl;}
}
bool DFSvisited[50];  //用于深搜的标记数组
bool BFSvisited[50];  //用于广搜的标记数组
void DFS(GraphAdjList  G,int i)
{EdgeNode * p;DFSvisited[i]=true;cout<<G.adjList[i].data<<"  ";p=G.adjList[i].firstedge;while(p){if(!DFSvisited[p->adjvex])DFS(G,p->adjvex);p=p->next;}
}
void DFSTraverse(GraphAdjList  G)
{for(int i=0; i<G.numVertex; i++)DFSvisited[i]=false;for(int i=0; i<G.numVertex; i++){if(!DFSvisited[i])DFS(G,i);}
}
void BFSTraverse(GraphAdjList  G)
{EdgeNode * p;queue<int>q;for(int i=0; i<G.numVertex; i++)BFSvisited[i]=false;for(int i=0; i<G.numVertex; i++){if(!BFSvisited[i]){BFSvisited[i]=true;cout<<G.adjList[i].data<<"  ";q.push(i);while(!q.empty()){int count =q.front();q.pop();p=G.adjList[count].firstedge;while(p){if(!BFSvisited[p->adjvex]){BFSvisited[p->adjvex]=true;cout<<G.adjList[p->adjvex].data<<"  ";q.push(p->adjvex);}p=p->next;}}}}
}int main(){GraphAdjList G;CreateGraph(G);Prin(G);cout << "BFS:" << endl;BFSTraverse(G);return 0;
}

运行截图

7-3. 将图以邻接矩阵存储,实现prim算法。

code

#include <bits/stdc++.h>
using namespace std;
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2typedef int Status;
typedef int ElemType;#define INFINITY 65535    //最大值∞
#define MAX_VERTEX_NUM 20 //最大顶点个数typedef int Status;
typedef int VRType;
typedef char InfoType;
typedef int VertexType;
typedef enum
{DG,DN,UDG,UDN
} GraphKind; //{有向图,有向网,无向图,无向网}typedef struct ArcCell
{VRType adj;     //VRType 是顶点关系类型。对无权图,用0或1表示相邻否;对带权图,则为权值类型InfoType *info; //该弧相关信息的指针
} ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
typedef struct
{VertexType vexs[MAX_VERTEX_NUM]; //顶点向量AdjMatrix arcs;                  //邻接矩阵int vexnum, arcnum;              //图的当前顶点数和弧数GraphKind kind;                  //图的种类标志
} MGraph;typedef struct
{VertexType adjvex;VRType lowcost;
} CLOSEDGE;/*******************************声明部分****************************************/
Status CreateUDN(MGraph *G);
//构造无向网
int LocateVex(MGraph G, VertexType v);
//确定v在G中的位置
int minimum(CLOSEDGE closedge[], int n);
//返回最小连接的顶点序号
void MiniSpanTree_PRIM(MGraph G, VertexType u);
//用普里姆算法从第u个顶点出发构造网G的最小生成树T,输出T的各条边
//记录从顶点集U到V-U的代价最小的边的辅助数组定义
/*******************************函数部分****************************************/
Status CreateUDN(MGraph *G)
{printf("\n构造无向网\n");int i, j, k;       //i,j,k用于计数int w;             //权重VertexType v1, v2; //弧头,弧尾printf("请输入顶点个数:");scanf("%d", &(*G).vexnum);printf("请输入弧个数:");scanf("%d", &(*G).arcnum);//假定该图不含其他信息int IncInfo = 0;cout << "依次输入顶点(空格隔开):\n";for (i = 0; i < (*G).vexnum; i++){scanf("%d", &(*G).vexs[i]);} //forfor (i = 0; i < (*G).vexnum; i++) //初始化邻接矩阵for (j = 0; j < (*G).vexnum; j++){(*G).arcs[i][j].adj = INFINITY; //无向网(*G).arcs[i][j].info = NULL;}printf("请输入弧头(初始点)、弧尾(终端点)、权值:\n"); //输入一条弧的始点和终点for (k = 0; k < (*G).arcnum; k++){    //构造邻接矩阵scanf("%d%d%d", &v1, &v2, &w);i = LocateVex(*G, v1);j = LocateVex(*G, v2);if (i >= 0 && j >= 0)(*G).arcs[i][j].adj = (*G).arcs[j][i].adj = w; //置<v1,v2>的对称弧<v2,v1>//不再输入该弧含有的相关信息}(*G).kind = UDN;return OK;
}int LocateVex(MGraph G, VertexType v)
{int ct;for (ct = 0; ct < G.vexnum; ct++)if (G.vexs[ct] == v)return ct;return -1;
}int minimum(CLOSEDGE closedge[], int n)
{int i = 0, j, min, k;while (!closedge[i].lowcost)i++;min = closedge[i].lowcost;k = i;for (j = 1; j < n; j++)if (closedge[j].lowcost)if (min > closedge[j].lowcost){min = closedge[j].lowcost;k = j;} //ifreturn k;
}void MiniSpanTree_PRIM(MGraph G, VertexType u)
{CLOSEDGE closedge[G.vexnum + 1];int k, j, i;k = LocateVex(G, u);for (j = 0; j < G.vexnum; ++j)if (j != k){ //辅助数组初始化closedge[j].adjvex = u;closedge[j].lowcost = G.arcs[k][j].adj;} //ifclosedge[k].lowcost = 0; //初始,U = {u}for (i = 1; i < G.vexnum; ++i){ //选择其余G.vexnum-1个顶点k = minimum(closedge, G.vexnum);                    //求出T的下一个结点:第k个顶点printf("(%d,%d)\n", closedge[k].adjvex, G.vexs[k]); //输出生成树的边closedge[k].lowcost = 0; //第k顶点并入U集for (j = 0; j < G.vexnum; ++j){if (G.arcs[k][j].adj < closedge[j].lowcost){ //新顶点并入U集后重新选择最小边closedge[j].adjvex = G.vexs[k];closedge[j].lowcost = G.arcs[k][j].adj;} //if}     //for}         //for
}/*******************************主函数部分**************************************/int main()
{MGraph G;printf("P174 图7.16(a)\n");CreateUDN(&G);printf("\n输出生成树上的5条边为:\n");MiniSpanTree_PRIM(G, 1);return 0;
}

运行截图

7-4. 将图以邻接表存储,实现Kruskal算法。

code

#include<iostream>
#define Vnum 10
#define MAX 10000
#include<string.h>
#include<algorithm>
using namespace std;
typedef char Datatype;
typedef struct arcnode{int adjvex;int weight;struct arcnode *nextarc;
} arcnode;
typedef struct{Datatype vexdata;arcnode *firstarc;
} Adjlist;
typedef struct{int arcnum, vexnum;Adjlist adjlist[Vnum];
} GraphTp;
int visit[Vnum];
int quan[Vnum][Vnum];
void creat(GraphTp *g){int i, j, k, ii, quanz;char tailarc, headarc;arcnode *p;cout << "enter vexnum and arcnum:" << endl;cin >> g->vexnum >> g->arcnum;cout << "enter the vexdata:" << endl;for (i = 0; i < g->vexnum; i++){cin >> g->adjlist[i].vexdata;g->adjlist[i].firstarc = NULL;}cout << "enter the arcdata:" << endl;for (ii = 0; ii < g->arcnum; ii++){cin >> tailarc >> headarc >> quanz;for (k = 0; k < g->vexnum; k++)if (g->adjlist[k].vexdata == tailarc){i = k;break;}for (k = 0; k < g->vexnum; k++)if (g->adjlist[k].vexdata == headarc){j = k;break;}p = new arcnode;p->adjvex = j;p->weight = quanz;quan[i][j] = quanz;quan[j][i] = quanz;//cout << "the data is:" << i << ' ' << j << ' ' << quanz << endl;p->nextarc = g->adjlist[i].firstarc;g->adjlist[i].firstarc = p;}
}
struct edge{int weight;int u, v;
} bian[Vnum];
int cmp(edge A, edge B){return A.weight < B.weight;
}
void Kruskal(int n, int C[Vnum][Vnum])   {  //Kuruskral算法,顶点数n,带权临接矩阵V[n][n]int i, j;int nodeset[n];                       //顶点所属集合,之后用于判断顶点是否在同一暂时的树中int count = 0;bool flag[n];                         //该数组用来判断顶点是否已经被选进生成树中for (i = 0; i < n; i++)     {           //将图中所有边存入数组边中nodeset[i] = i;flag[i] = false;for (j = 0; j < n; j++)if (C[i][j] < MAX)       {bian[count].u = i;bian[count].v = j;bian[count].weight = C[i][j];count++;}}sort(bian, bian + count, cmp);           /*将图中各边权值升序排列*/int edgeset = 0;int w = 0;                             /*用来存放生成树总权值*/count = 0;while (edgeset < n - 1)      {       /*核心算法*/if (!flag[bian[count].u] && flag[bian[count].v]){ /*u未加入某一集合,v已经加入某个集合, 这个集合由已经找到的生成树顶点组成,开始可能形成多个*/w += bian[count].weight;flag[bian[count].u] = true;nodeset[bian[count].u] = nodeset[bian[count].v];edgeset++;}else if (flag[bian[count].u] && !flag[bian[count].v])/*v未加入,u已经加入*/{w += bian[count].weight;flag[bian[count].v] = true;nodeset[bian[count].v] = nodeset[bian[count].u];edgeset++;}else if (!flag[bian[count].u] && !flag[bian[count].v])            /*两个都未加入*/{w += bian[count].weight;flag[bian[count].u] = true;flag[bian[count].v] = true;nodeset[bian[count].u] = nodeset[bian[count].v];edgeset++;}else if (nodeset[bian[count].u] != nodeset[bian[count].v])/*如果两个加入集合,判断加入集合是否相同,相同说明形成环,跳出此次循环,转向下一次。*/{                                                      /*否则将两个集合合并*/w += bian[count].weight;edgeset++;int tmp = nodeset[bian[count].v];for (i = 0; i < n; i++)if (nodeset[i] = tmp)nodeset[i] = nodeset[bian[count].u];}count++;                          /*转向次小边,进行下一次判断*/}cout << "该图权值是:" << w;              /*输出权值*/
}
int main()
{int i, j;for (i = 0; i < Vnum; i++)for (j = 0; j < Vnum; j++)quan[i][j] = MAX;GraphTp g;creat(&g);cout << endl;Kruskal(g.vexnum, quan);return 0;
}

运行截图

7-5.将图以邻接矩阵或邻接表存储,实现Dijkstra算法。

code

#include<bits/stdc++.h>
using namespace std;/* 函数结果状态代码 */
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int Status;
typedef int Boolean;
#define MAX_NAME 5
#define MAX_INFO 20
typedef int VRType;
typedef char InfoType;
typedef char VertexType[MAX_NAME];/* ---------------------------------  图的数组(邻接矩阵)存储表示    --------------------------------*/#define INFINITY INT_MAX
#define MAX_VERTEX_NUM 20
typedef enum { DG, DN, AG, AN }GraphKind;
typedef struct{VRType adj; InfoType *info;
}ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
typedef struct{VertexType vexs[MAX_VERTEX_NUM];AdjMatrix arcs; int vexnum, arcnum; GraphKind kind;
}MGraph;typedef int PathMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
typedef int ShortPathTable[MAX_VERTEX_NUM];/* ---------------------------  需要用的图的数组(邻接矩阵)存储的基本操作 --------------------------*/int LocateVex(MGraph G, VertexType u){
/*  初始条件:图G存在,u和G中顶点有相同特征 操作结果:若G中存在顶点u,则返回该顶点在图中位置;否则返回-1 */int i;for (i = 0; i < G.vexnum; ++i)if (strcmp(u, G.vexs[i]) == 0)return i;return -1;
}Status CreateDN(MGraph &G){int i, j, k, w, IncInfo;char s[MAX_INFO], *info;VertexType va, vb;printf("请输入有向网G的顶点数,弧数,弧是否含其它信息(是:1,否:0)(以空格作为间隔): ");scanf("%d%d%d", &G.vexnum, &G.arcnum, &IncInfo);printf("请输入%d个顶点的值(<%d个字符):\n", G.vexnum, MAX_NAME);for (i = 0; i < G.vexnum; ++i) scanf("%s", G.vexs[i]);for (i = 0; i < G.vexnum; ++i) for (j = 0; j < G.vexnum; ++j){G.arcs[i][j].adj = INFINITY; G.arcs[i][j].info = NULL;}printf("请输入%d条弧的弧尾 弧头 权值(以空格作为间隔): \n", G.arcnum);for (k = 0; k < G.arcnum; ++k){scanf("%s%s%d%*c", va, vb, &w);  i = LocateVex(G, va);j = LocateVex(G, vb);G.arcs[i][j].adj = w;if (IncInfo){printf("请输入该弧的相关信息(<%d个字符): ", MAX_INFO);gets(s);w = strlen(s);if (w){info = (char*)malloc((w + 1) * sizeof(char));strcpy(info, s);G.arcs[i][j].info = info; }}}G.kind = DN;return OK;
}//算法7.15
void ShortestPath_DIJ(MGraph G, int v0, PathMatrix &P, ShortPathTable &D){
/*  用Dijkstra算法求有向网G的v0顶点到其余顶点v的最短路径P[v]及带权长度 D[v]。若P[v][w]为TRUE,则w是从v0到v当前求得最短路径上的顶点。 final[v]为TRUE当且仅当v∈S,即已经求得从v0到v的最短路径 算法7.15 */int v, w, i, j, min;Status final[MAX_VERTEX_NUM];for (v = 0; v < G.vexnum; ++v){final[v] = FALSE;D[v] = G.arcs[v0][v].adj;for (w = 0; w < G.vexnum; ++w)P[v][w] = FALSE; if (D[v] < INFINITY){P[v][v0] = TRUE;P[v][v] = TRUE;}}D[v0] = 0;final[v0] = TRUE;               // 初始化,v0顶点属于S集 for (i = 1; i < G.vexnum; ++i)    //其余G.vexnum-1个顶点 {                                 // 开始主循环,每次求得v0到某个v顶点的最短路径,并加v到S集 min = INFINITY;                      // 当前所知离v0顶点的最近距离 for (w = 0; w < G.vexnum; ++w)if (!final[w])                        // w顶点在V-S中 if (D[w] < min){v = w;min = D[w];}                                 //w顶点离v0顶点更近 final[v] = TRUE;                      // 离v0顶点最近的v加入S集 for (w = 0; w < G.vexnum; ++w) {     // 更新当前最短路径及距离 if (!final[w] && min < INFINITY&&G.arcs[v][w].adj < INFINITY && (min + G.arcs[v][w].adj < D[w])){D[w] = min + G.arcs[v][w].adj;for (j = 0; j < G.vexnum; ++j)P[w][j] = P[v][j];P[w][w] = TRUE;}}}
}int main(){int i, j, v0 = 0; MGraph g;PathMatrix p;ShortPathTable d;CreateDN(g);ShortestPath_DIJ(g, v0, p, d);printf("最短路径数组 PathMatrix[i][j] 如下:\n");for (i = 0; i < g.vexnum; ++i){for (j = 0; j < g.vexnum; ++j)printf("%2d", p[i][j]);printf("\n");}printf("%s到各顶点的最短路径长度为:\n", g.vexs[0]);for (i = 1; i < g.vexnum; ++i)printf("%s-%s:%d\n", g.vexs[0], g.vexs[i], d[i]);return 0;
}

运行截图

2021-12-11 【数据结构平时实验】【图】相关推荐

  1. 武汉理工大学数据结构综合实验——图与景区信息管理系统实践

    文章目录 实验目的 主要仪器设备及耗材 一.实验要求 二.分析与设计 1.数据结构的设计 2.核心算法设计 改进DFS算法 搜索最短路径 Prim算法(构建最小生成树) 3.测试用例设计 4.测试结果 ...

  2. 2021.12.11 新星杯简单总结

    这次新星杯刚开始可自信了,感觉这次可把自己牛坏了.刚开始见一个会一个的感觉,什么开根,什么简单数学(两点之间距离),什么dfs,什么递归,什么排序见一个会一个,网站崩的时候写的可顺畅了,一口气儿写了5 ...

  3. 2021.12.11 烹饪

    [题目描述]  Tom将烹饪N道菜,编号分别为1到N.  第i道菜需要用烤箱连续烤Ti分钟,一个烤箱不能同时用于两道或两道以上的菜肴.  如果Tom有两个烤箱可供使用,那么烹调所有N道菜所需的最短时间 ...

  4. 数据结构java 图实验代码_20172329 2018-2019 《Java软件结构与数据结构》实验三报告...

    20172329 2018-2019-2 <Java软件结构与数据结构>实验三报告 课程:<Java软件结构与数据结构>html 班级: 1723java 姓名: 王文彬lin ...

  5. 蓝牙AOA高精度定位基站原厂深圳核芯物联科技参加2021中国国际高新技术成果交易会诚邀生态合作伙伴莅临交流指导2021.12.27-29深圳宝安国际会展中心11号馆

    蓝牙AOA高精度定位基站原厂深圳核芯物联科技参加2021中国国际高新技术成果交易会诚邀生态合作伙伴莅临交流指导2021.12.27-29深圳宝安国际会展中心11号馆 核芯物联岳毅恒 核芯物联岳毅恒 ​ ...

  6. 任天堂推出《塞尔达传说》GAMEampWATCH游戏机,预计要在 2021 年 11 月 12 日推出塞尔达版本的 GAMEampWATCH

    模玩资讯:任天堂推出<塞尔达传说>GAME&ampWATCH游戏机 任天堂将自家起底基业商品GAME&ampWATCH结合招牌游戏有奇效!继去年此时推出<超级玛利欧兄 ...

  7. 【数据结构 图】数据结构实验--图及其应用

    数据结构实验–图及其应用 (代码有一些纰漏 仅供自己后期修改保存用) 数据结构上机实验 题目:设计并验证如下算法: 带权图采用邻接表表示,实现无向图的广度优先搜索BFS与有向图的深度优先搜索DFS. ...

  8. 数据结构实验-图-普里姆算法、克鲁斯科尔算法

    数据结构实验-图-普里姆算法.克鲁斯科尔算法 (实验)自定义存储结构,并设计程序完成如下功能: ①创建图:创建带权无向图. ②普里姆算法:采用普里姆算法依次输出最小生成树中各条边. ③克鲁斯科尔算法: ...

  9. 20172328《程序设计与数据结构》实验二:树

    20172328<程序设计与数据结构>实验二:树 课程:<软件结构与数据结构> 班级: 1723 姓名: 李馨雨 学号:20172328 实验教师:王志强老师 实验日期:201 ...

  10. 《安富莱嵌入式周报》第245期:2021.12.20--2021.12.26

    往期周报汇总地址:嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - P ...

最新文章

  1. 谷歌程序员少输一个“”,差点让全球Chrome笔记本变砖
  2. Windows server 2008,Windows server 2008 R2,Windows 2008 SP2 区别
  3. 解决magento保存产品时耗时很长的问题
  4. MySql的存储过程介绍及语法实例操作
  5. 接口与抽象类区别和接口jdk8新特性
  6. 说一说JavaScript 中的原型ProtoType
  7. linux系统中怎么设置网络,vmware中linux怎么设置网络
  8. Python数据结构实战——哈希表中的冲突处理(Collision Handling In Hash Table)
  9. 爬取CSDN博客文章,统计文章历史数据
  10. 送抖音直播云挤地铁教程
  11. 运维小知识---If you insist running as root, then set the environment variable RUN_AS_USER=root...
  12. 环境保护概论课程作业
  13. 用C语言循环码,xinxilunyubianma
  14. PHP除数取余数,php相除取余数的实现方法
  15. 微信小程序接入知晓云插件sdk入门
  16. Linux/Android——usb触摸屏驱动 - usbtouchscreen (一)
  17. iOS11正式版亮点
  18. 强大的Java前台后台开发工具
  19. Oracle 取第一个、最后一个和上一个、下一个函数详解(first_value、last_value 和 lag、lead)
  20. 华为交换机ftp\telnet\ssh功能配置指导

热门文章

  1. 微信第三方服务商更新ticket时,aes解密失败
  2. java 判断是否为英文字母_java判断是否是26个英文字母代码示例
  3. python3中26个英文字母排序_26个英文字母的排序是怎样排的?
  4. 天骄辅助外挂制作,寻求合作
  5. photoshop技巧分享:psd格式批量转换jpg格式一键完成
  6. 建行u盾弹不出来_Win7系统检测不到建行网银U盾无法识别的解决方法
  7. arcgis符号库匹配不对的原因_ArcGIS符号库自动匹配方法
  8. 人工智能:神经网络与深度学习
  9. VHDL实现数码管的动态扫描(可以连接其他的模块)
  10. STM32学习记录——MD300二维码扫描模块