【C 数据结构-图】2. 图的存储结构

文章目录

  • 【 1. 图的顺序存储结构 】
    • 1.1 基本原理
    • 1.2 顺序存储结构的 C 实现
  • 【 2. 图的链式存储结构 】
    • 2.1 图的临接表存储结构
      • 2.1.1 临接表的 基本原理
      • 2.1.2 临接表的 链表节点
      • 2.1.3 邻接表 各结构体的C实现
      • 2.1.4 临接表 计算顶点的出度和入度
        • 邻接表计算 无向图的出度和入度
        • 邻接表计算 有向图的出度和入度
    • 2.2 图的十字链表存储结构
      • 2.2.1 十字链表的 基本原理
      • 2.2.2 十字链表的 链表节点
      • 2.2.3 十字链表的 C实现
    • 2.3 图的临接多重表存储结构
      • 2.3.1 临接多重表的 基本原理
      • 2.3.2 临接多重表的 链表节点
      • 2.3.3 临接多重表的 C 实现
  • 【 3. 图的各存储结构的对比 】

【 1. 图的顺序存储结构 】

1.1 基本原理

  • 图可以采用顺序存储(也就是使用 数组 有效地存储),使用数组存储图时,需要使用 两个数组
    • 数据数组:存放图中顶点本身的数据(一维数组:存储图中各顶点本身数据,使用一维数组就足够了);
    • 临接矩阵(关系数组):用于存储各顶点之间的关系(二维数组:存储顶点之间的关系时,要记录每个顶点和其它所有顶点之间的关系,所以需要使用二维数组)。临接矩阵中值的确定如下:
      • 在使用二维数组存储 无权值 的图 中顶点之间的关系时,如果顶点之间 存在边或弧,在相应位置用 1 表示,反之用 0 表示
      • 如果使用二维数组存储 有权值 的图即网 中顶点之间的关系,顶点之间如果 有边或者弧的存在,在数组的相应位置存储其权值;反之用 0 表示
  • 数组 可用于存储 无向图有向图

例如:存储下图中的两张图时,除了存储图中各顶点本身具有的数据外,还需要使用二维数组存储任意两个顶点之间的关系。
在这里插入图片描述

  • 存储上图中的有向图(A)时,对应的二维数组如下图所示:
    例如,arcs[0][1] = 1 ,证明从 V1 到 V2 有弧存在。且通过该矩阵,可以很轻松得知各顶点的出度和入度,出度为该行非 0 值的和,入度为该列非 0 值的和。例如,V1 的出度为第一行两个 1 的和 为 2 ; V1 的入度为第一列中 1 的和 为 1 。所以 V1 的出度为 2 ,入度为 1 ,度为两者的和 3 。
    在这里插入图片描述
  • 存储上上图中的无向图(B)时,由于各顶点没有权值,所以如果两顶点之间有关联,相应位置记为 1 ;反之记为 0 。构建的二维数组如下图所示:
    在此二维数组中,每一行代表一个顶点,依次从 V1 到 V5 ,每一列也是如此。比如 arcs[0][1] = 1 ,表示 V1 和 V2 之间有边存在;而 arcs[0][2] = 0,说明 V1 和 V3 之间没有边。通过该矩阵,可以直观地判断出各个顶点的度,为该行(或该列)非 0 值的和。例如,第一行有两个 1,说明 V1 有两个边,所以度为 2。
    在这里插入图片描述

1.2 顺序存储结构的 C 实现

  • 在此程序中,构建无向网或有向网时,对于之间没有边或弧的顶点,相应的二阶矩阵中存放的是 0,目的只是为了方便查看运行结果。而实际上 如果顶点之间没有关联,则关系数组对应位置上的值应该是无穷大 ∞,以表示距离无穷远,根本无法到达
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#define MAX_VERtEX_NUM 20  //顶点的最大个数
#define VertexType int     //顶点的数据类型
#define VRType int         //表示顶点之间的关系的变量类型
#define InfoType char      //存储弧或者边额外信息的指针变量类型
typedef enum { DG, DN, UDG, UDN }GraphKind;  //枚举图的 4 种类型:0无权有向、1无权无向、2有权有向、3有权无向// 边/弧 的信息结构体,包括权值和附加其他信息
typedef struct {VRType adj;     //对于无权图,用 1 或 0 表示是否相邻;对于带权图,直接为权值。InfoType* info; //弧或边额外含有的信息指针
}ArcCell, AdjMatrix[MAX_VERtEX_NUM][MAX_VERtEX_NUM];//图结构体
typedef struct {VertexType vexs[MAX_VERtEX_NUM];  //一维数据数组AdjMatrix arcs;                   //二维关系数组(邻接矩阵),每个元素为1个ArcCell信息结构体int vexnum, arcnum;               //图的顶点数和 弧/边 数GraphKind kind;                   //图的种类
}MGraph;//根据顶点本身数据值,判断出顶点在二维数组中的位置
int LocateVex(MGraph* G, VertexType v) {int i = 0;//遍历一维数组,找到变量vfor (; i < G->vexnum; i++) {if (G->vexs[i] == v) {break;}}//如果找不到,输出提示语句,返回-1if (i > G->vexnum) {printf("no such vertex.\n");return -1;}return i;
}
//构造无权有向图
void CreateDG(MGraph* G) {//输入图含有的顶点数和弧的个数scanf("%d,%d", &(G->vexnum), &(G->arcnum));//依次输入顶点本身的数据for (int i = 0; i < G->vexnum; i++) {scanf("%d", &(G->vexs[i]));}//初始化二维矩阵,全部归0,指针指向NULLfor (int i = 0; i < G->vexnum; i++) {for (int j = 0; j < G->vexnum; j++) {G->arcs[i][j].adj = 0;G->arcs[i][j].info = NULL;}}//在二维数组中添加弧的数据for (int i = 0; i < G->arcnum; i++) {int v1, v2;//输入弧头和弧尾scanf("%d %d", &v1,&v2);//确定顶点位置int n = LocateVex(G, v1);int m = LocateVex(G, v2);//排除错误数据if (m == -1 || n == -1) {printf("no this vertex\n");return;}//将正确的弧的数据加入二维数组G->arcs[n][m].adj = 1;}
}
//构造无权无向图
void CreateDN(MGraph* G) {scanf("%d %d", &(G->vexnum), &(G->arcnum));for (int i = 0; i < G->vexnum; i++) {scanf("%d", &(G->vexs[i]));}for (int i = 0; i < G->vexnum; i++) {for (int j = 0; j < G->vexnum; j++) {G->arcs[i][j].adj = 0;G->arcs[i][j].info = NULL;}}for (int i = 0; i < G->arcnum; i++) {int v1, v2;scanf("%d,%d", &v1, &v2);int n = LocateVex(G, v1);int m = LocateVex(G, v2);if (m == -1 || n == -1) {printf("no this vertex\n");return;}G->arcs[n][m].adj = 1;G->arcs[m][n].adj = 1;//无向图的二阶矩阵沿主对角线对称}
}
//构造有权有向网
void CreateUDG(MGraph* G) {scanf("%d %d", &(G->vexnum), &(G->arcnum));for (int i = 0; i < G->vexnum; i++) {scanf("%d",&(G->vexs[i]));}for (int i = 0; i < G->vexnum; i++) {for (int j = 0; j < G->vexnum; j++) {G->arcs[i][j].adj = 0;G->arcs[i][j].info = NULL;}}for (int i = 0; i < G->arcnum; i++) {int v1, v2, w;scanf("%d %d %d", &v1, &v2, &w);int n = LocateVex(G, v1);int m = LocateVex(G, v2);if (m == -1 || n == -1) {printf("no this vertex\n");return;}G->arcs[n][m].adj = w;}
}
//构造有权无向网
void CreateUDN(MGraph* G) {scanf("%d %d", &(G->vexnum), &(G->arcnum));for (int i = 0; i < G->vexnum; i++) {scanf("%d", &(G->vexs[i]));}for (int i = 0; i < G->vexnum; i++) {for (int j = 0; j < G->vexnum; j++) {G->arcs[i][j].adj = 0;G->arcs[i][j].info = NULL;}}for (int i = 0; i < G->arcnum; i++) {int v1, v2, w;scanf("%d %d %d", &v1, &v2, &w);int m = LocateVex(G, v1);int n = LocateVex(G, v2);if (m == -1 || n == -1) {printf("no this vertex\n");return;}G->arcs[n][m].adj = w;G->arcs[m][n].adj = w;//矩阵对称}
}
void CreateGraph(MGraph* G) {//选择图的类型scanf("%d", &(G->kind));//根据所选类型,调用不同的函数实现构造图的功能switch (G->kind) {case DG:return CreateDG(G);break;case DN:return CreateDN(G);break;case UDG:return CreateUDG(G);break;case UDN:return CreateUDN(G);break;default:break;}
}
//输出函数
void PrintGrapth(MGraph G)
{for (int i = 0; i < G.vexnum; i++){for (int j = 0; j < G.vexnum; j++){printf("%d ", G.arcs[i][j].adj);}printf("\n");}
}int main()
{MGraph G;//建立一个图的变量,对象CreateGraph(&G);//调用创建函数,传入地址参数,进行初始化PrintGrapth(G); //输出图的二阶矩阵return 0;
}
  • 例如,使用上述程序存储下图 (a)的有向网时,存储的两个数组如下图 (b)所示:
    在这里插入图片描述
//输入下列数据:
2
6 10
1
2
3
4
5
6
1 2 5
2 3 4
3 1 8
1 4 7
4 3 5
3 6 9
6 1 3
4 6 6
6 5 1
5 4 5

在这里插入图片描述

【 2. 图的链式存储结构 】

  • 通常,图更多的是采用链表存储,具体的存储方法有 3 种,分别是邻接表、邻接多重表和十字链表。

2.1 图的临接表存储结构

2.1.1 临接表的 基本原理

  • 如果图中的两个点相互连通,即通过其中一个顶点,可直接找到另一个顶点,则称它们互为 邻接点 邻接 指的是图中顶点之间有边或者弧的存在。邻接表 可用于存储 无向图有向图
  • 邻接表的实现方式:
    • 给图中的各个顶点独自建立一个链表,用 首元节点存储该顶点,用链表中 其他节点存储各自的临接点
    • 同时,为了便于管理这些链表,通常会将所有 链表的头节点存储到数组中(也可以用链表存储), 各链表在存储顶点的临接点时,仅需存储该邻接点位于数组中的下标 即可。
  • 例如,存储下图 a 所示的有向图,其对应的邻接表如下图 b 所示:
    以顶点 V1 为例,与其相关的邻接点分别为 V2 和 V3,因此存储 V1 的链表中存储的是 V2 和 V3 在数组中的位置下标 1 和 2。
    在这里插入图片描述
  • 对于具有 n 个顶点和 e 条边的无向图,邻接表中需要存储 n 个头结点和 2e 个链表中的结点。在图中边或者弧稀疏的时候,使用邻接表(所有链表中的节点总数为 n + 2 e n+2e n+2e)要比图的顺序存储结构中的邻接矩阵(数组大小为 n 2 n^2 n2) 更加节省空间。

2.1.2 临接表的 链表节点

  • 存储各顶点的节点结构分为两部分,数据域和指针域。data 数据域用于存储顶点数据信息,next 指针域用于指向下一个临接点,如下图所示:
    在这里插入图片描述
  • 在实际应用中,除了上图这种节点结构外,对于用临接表存储网(边或弧存在权)结构,还需要节点存储权的值,因此需使用下图中的节点结构:adjvex为邻接点在数组中的下标,next指针指向下一个节点,info 表示 adjvex 所代表的顶点与临接表表头所代表顶点的权值。
    在这里插入图片描述

2.1.3 邻接表 各结构体的C实现

  • 邻接表 各结构体的 C 实现:
#define  MAX_VERTEX_NUM 20	//顶点的最大个数
#define  VertexType int		//顶点的数据类型
#define  InfoType int		//弧或者边包含的信息的类型//各顶点的临接点结构体
typedef struct ArcNode{int adjvex;//邻接点在数组中的下标struct ArcNode * nextarc;//指向下一个邻接点InfoType * info;//信息域
}ArcNode;//图的顶点结构体
typedef struct VNode{VertexType data;   //顶点的数据域ArcNode * firstarc;//指向邻接点的指针
}VNode,AdjList[MAX_VERTEX_NUM];//存储各链表头结点的数组//图结构体
typedef struct {AdjList vertices;  //图中顶点的数组int vexnum,arcnum; //图中顶点数和边/弧数int kind; //图的种类
}ALGraph;

2.1.4 临接表 计算顶点的出度和入度

邻接表计算 无向图的出度和入度
  • 使用邻接表 计算 无向图 中顶点的入度和出度只需从数组中 找到该顶点然后统计此链表中节点的数量 即可
邻接表计算 有向图的出度和入度
  • 使用 邻接表存储 有向图 时,通常各个顶点的链表中存储的都是以该顶点为弧尾的邻接点,因此 通过统计各顶点链表中的节点数量, 只能计算出该顶点的出度,而无法计算该顶点的入度
  • 对于利用邻接表求某顶点的入度,有两种方式:
    ① 遍历整个邻接表中的节点,统计除了该顶点外所有的链表中与该顶点所在数组位置下标相同的节点数量,即为该顶点的入度;
    ② 建立一个 逆邻接表,该表中的各顶点链表专门用于存储以此顶点为弧头的所有顶点在数组中的位置下标。
    比如说,建立一张2.1.1中图 a 对应的逆邻接表,如下图所示:
    以 V1 为例,其他顶点中能到达 V1 的顶点为V4,故 顶点V1的链表中第二个节点存储的是 V4 所在数组的下标3。
    在这里插入图片描述

2.2 图的十字链表存储结构

2.2.1 十字链表的 基本原理

  • 十字链表法 仅适用于 存储有向的,即 有向图有向网。不仅如此,十字链表法还 解决了邻接表不方便计算有向图顶点入度的问题
  • 十字链表存储有向图(网)的方式与邻接表有一些相同,都 以图(网)中各顶点为首元节点 建立多条链表,同时为了便于管理,还将所有链表的首元节点存储到同一数组(或链表)中。
  • 十字链表实质上就是为每个顶点建立两个链表,分别存储以该顶点为弧头的所有顶点和以该顶点为弧尾的所有顶点 。对于各个链表中节点来说,由于表示的都是该顶点的出度或者入度,因此 十字链表中的节点没有先后次序之分

2.2.2 十字链表的 链表节点

  • 十字链表中用于存储顶点的 顶点结构体 节点如下图所示:
    • data :用于存储该顶点中的数据;
    • firstin 指针:用于连接以当前顶点为弧头的其他顶点构成的链表;
    • firstout 指针:用于连接以当前顶点为弧尾的其他顶点构成的链表;
      在这里插入图片描述
  • 十字链表中 弧结构体 节点如下图所示:
    • tailvex: 存储该弧弧尾的顶点位于数组中的下标;
    • headvex:存储该弧弧头的顶点位于数组中的下标;
    • hlink 指针:指向下一个与该弧弧头相同的弧的节点;
    • tlink 指针:指向下一个与该弧弧尾相同的弧的节点;
    • info 指针(可选):用于存储与该顶点相关的信息,例如两顶点之间的权值;
      在这里插入图片描述
  • 例如,用十字链表存储下图 a 中的有向图,存储状态如下图 b 所示:
    • 以顶点 V1 为例,以 V1 为弧头的弧只有 V4→V1。因此,V1 的 firstin 指针指向 V4→V1 这条弧,而在 剩下的弧中没有与 V4→V1 这条弧弧头相同的节点,故 V4→V1 这条弧的 hlink 指针指向空。如图中红色颜色所示。
    • 同样,以 V1 为弧尾的弧有 V1→V2 和 V1→V3(不区分先后次序)这两条弧。因此,V1 的 firstout 指针指向 V1→V2 这条弧的节点, V1→V2 这条弧的 tlink 指针指向 V1→V3 这条弧, V1→V3 这条弧的 tlink 指针指向空。如图中棕色颜色所示。

在这里插入图片描述

2.2.3 十字链表的 C实现

#define  MAX_VERTEX_NUM 20
#define  InfoType int//图中弧包含信息的数据类型
#define  VertexType int//链表中的其他节点结构体
typedef struct ArcBox 
{int tailvex, headvex;//弧尾、弧头对应顶点在数组中的位置下标struct ArcBox* hlik, * tlink;//分别指向弧头相同和弧尾相同的下一个弧InfoType* info;//存储弧相关信息的指针
}ArcBox;//链表的首元节点结构体
typedef struct VexNode 
{VertexType data;//顶点的数据域ArcBox* firstin, * firstout;//指向以该顶点为弧头和弧尾的链表首个结点
}VexNode;//图结构体
typedef struct 
{VexNode xlist[MAX_VERTEX_NUM];//存储顶点的一维数组int vexnum, arcnum;//记录图的顶点数和弧数
}OLGraph;int LocateVex(OLGraph* G, VertexType v)
{int i = 0;//遍历一维数组,找到变量vfor (; i < G->vexnum; i++) {if (G->xlist[i].data == v) {break;}}//如果找不到,输出提示语句,返回 -1if (i >= G->vexnum) {printf("no such vertex.\n");return -1;}return i;
}
//构建十字链表函数
void CreateDG(OLGraph* G) {//输入有向图的顶点数和弧数scanf("%d,%d", &(G->vexnum), &(G->arcnum));//使用一维数组存储各顶点数据,初始化指针域为NULLfor (int i = 0; i < G->vexnum; i++) {scanf("%d", &(G->xlist[i].data));G->xlist[i].firstin = NULL;G->xlist[i].firstout = NULL;}//构建十字链表for (int k = 0; k < G->arcnum; k++) {int v1, v2;scanf("%d,%d", &v1, &v2);//确定v1、v2在数组中的位置下标int i = LocateVex(G, v1); //弧的尾的下标int j = LocateVex(G, v2); //弧的头的下标  i→j//建立弧的其他节点ArcBox* p = (ArcBox*)malloc(sizeof(ArcBox));p->tailvex = i;p->headvex = j;//采用头插法插入新的p结点p->tlink = G->xlist[i].firstout;p->hlik =  G->xlist[j].firstin;G->xlist[j].firstin = G->xlist[i].firstout = p;}
}

2.3 图的临接多重表存储结构

2.3.1 临接多重表的 基本原理

  • 问题背景
    无向图的存储可以使用邻接表,但在实际使用时,如果想对图中某顶点进行实操(修改或删除),由于邻接表中存储该顶点的节点有两个,因此需要操作两个节点。
    而无向图的另一种存储结构—— 邻接多重表 可以提高无向图中操作顶点的效率
  • 邻接多重表 仅适用于 存储无向的,即无向图或无向网。
  • 邻接多重表存储无向图的方式,可看作是邻接表和十字链表的结合。同邻接表和十字链表存储图的方法相同,都是独自为图中各顶点建立一张链表,存储各顶点的节点作为各链表的首元节点,同时为了便于管理将各个首元节点存储到一个数组中。

2.3.2 临接多重表的 链表节点

  • 邻接多重表采用与邻接表相同的首元节点结构, 顶点结构体 节点 如下图所示:
    • data:存储此顶点的数据;
    • firstedge:指针域,指向同该顶点有直接关联的存储其他顶点的节点。
      在这里插入图片描述
  • 临接多重表的各链表中 边结构体 节点如下图所示:
    • mark:标志域,用于标记此节点是否被操作过,例如在对图中顶点做遍历操作时,为了防止多次操作同一节点,mark 域为 0 表示还未被遍历;mark 为 1 表示该节点已被遍历;
    • ivex 和 jvex:数据域,分别存储图中各边两端的顶点所在数组中的下标;
    • ilink:指针域,指向下一个以 ivex 为顶点的边结构体;
    • jlink:指针域,指向下一个以 jvex 为顶点的边结构体;
    • info:指针域,用于存储与该顶点有关的其他信息,比如无向网中各边的权;
      在这里插入图片描述
  • 如果我们想使用邻接多重表存储下图 a 中的无向图,则与之对应的邻接多重表如下图 b 所示:
    • 以顶点 V1 为例,以 V1 为顶点的边有 V1-V2 和 V1-V4(不区分先后次序)这两条边。因此,V1 的 firstedge 指针指向 V1-V2 这条边的节点, V1-V2 这条边的 ilink 指针指向 V1-V4 这条边的节点, V1-V4 这条边的 ilink 指针指向空。如图中棕色颜色所示。

在这里插入图片描述

2.3.3 临接多重表的 C 实现

#define MAX_VERTEX_NUM 20                   //图中顶点的最大个数
#define VertexType int                      //图顶点的数据类型
#define InfoType int                        //边含有的信息域的数据类型
typedef enum { unvisited, visited }VisitIf; //边标志域//边结构体
typedef struct EBox {VisitIf mark;                  //标志域int ivex, jvex;                //边的两个顶点在数组中的位置下标struct EBox* ilink, * jlink;   //分别指向与ivex、jvex相关的下一个边InfoType* info;                //边包含的其它的信息域的指针
}EBox;//顶点的首元节点结构体
typedef struct VexBox {VertexType data;               //顶点数据域EBox* firstedge;               //顶点相关的第一条边的指针域
}VexBox;//图结构体
typedef struct {VexBox adjmulist[MAX_VERTEX_NUM]; //图中顶点的数组int vexnum, degenum;              //图中顶点的个数和边的个数
}AMLGraph;

【 3. 图的各存储结构的对比 】

图的存储结构可存储的图的类型核心实现优点缺点
数组有向、无向一维数组存储顶点数据,二维数组存储各顶点间的关系。\\
临接表有向、无向一维数组存储各顶点的结构体(顶点结构体存储该顶点的数据和指向该顶点临接点结构体的指针);
临接点结构体中包括该临接点的数据下标和指向下一个临接点结构体的指针。
\不方便计算有向图中顶点的入度;
不方便操作无向图的顶点
十字链表有向一维数组存储各顶点的结构体(顶点结构体存储各顶点的数据和两个分别指向以该顶点为弧头和弧尾的弧结构体的指针);
弧结构体中存储该弧弧头和弧尾的数据下标、两个分别指向下一个与该弧弧头或弧尾相同的弧的弧结构体。
解决了邻接表不方便计算有向图顶点入度的问题。不能存储无向的
临接多重表无向一维数组存储各顶点的结构体(顶点结构体存储各顶点的数据和指向以该顶点为端点的边结构体的指针);
边结构体存储该边是否被操作过的标记位、该边两个顶点的数据下标、两个分别指向下一个与该边顶点相同的边结构体。
解决了临接表不方便操作无向图顶点的问题。不能存储有向的

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

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

相关文章

传统汽车空调系统工作原理

1.首先讲一个概念 液体变成气体&#xff1a;吸热 气体变成液体&#xff1a;放热 2.在汽车空调系统中热量的传递的介质不是水&#xff0c;而是氟利昂&#xff0c;简称&#xff1a;“氟”。 3.传统式汽车空调结构如下 该三个部件位于车头进气口位置 该部位位于汽车驾驶车厢前方…

基于FPGA的累加器及数码管显示VHDL代码Quartus仿真

名称&#xff1a;基于FPGA的累加器及数码管显示VHDL代码Quartus仿真&#xff08;文末获取&#xff09; 软件&#xff1a;Quartus 语言&#xff1a;VHDL 代码功能&#xff1a; 累加器及数码管显示 1、可以通过按键输入1~9 2、数字输入后进行累加&#xff0c;将累加结果显示…

英语新概念2-回译法-lesson12

第一次翻译 &#xff08;稀巴烂&#xff09; Our neiborhood,Capitain Charles Alison,will sail from P. We will ______ in the _. He will sit in his small boat, Topsail,Topsail is a famous boat. It has been across the A many times. Alison will sail at 8 o’cloc…

微信报名活动链接怎么做

在数字营销日新月异的今天&#xff0c;微信作为拥有数亿用户的社交平台&#xff0c;早已成为品牌宣传的重要阵地。而微信报名活动链接&#xff0c;更是品牌吸引用户参与、提升活动影响力的关键工具。今天&#xff0c;就让我们一起探讨如何制作一个引人入胜的微信报名活动链接&a…

️测试问我:为啥阅读量计数这么简单的功能你都能写出bug?

前言 可乐他们团队最近在做一个文章社区平台,由于人手不够,后端部分也是由前端同学来实现,使用的是 nest 。 今天他接到了一个需求,就是在用户点开文章详情的时候,把阅读量 +1 ,这里不需要判断用户是否阅读过,无脑 +1 就行。 它心想:这么简单,这不是跟 1+1 一样么。…

电脑提示mfc140u.dll文件丢失了?怎么快速修复mfc140u.dll文件

当你的电脑提示你的mfc140u.dll文件丢失了&#xff0c;那么就要小心了&#xff0c;可能你的某些程序出问题了&#xff01;这时候需要我们去进行相关的修复&#xff0c;只有修复了这个mfc140u.dll文件&#xff0c;才能正常的使用某些程序。下面一起来了解一下mfc140u.dll文件吧。…

springboot3 集成spring-authorization-server (一 基础篇)

官方文档 Spring Authorization Server 环境介绍 java&#xff1a;17 SpringBoot&#xff1a;3.2.0 SpringCloud&#xff1a;2023.0.0 引入maven配置 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter…

C++细节,可能存在的隐患,面试题03

文章目录 11. C编译过程12. const vs #define12.1. 全局const vs 局部const 13. C内存分区14. C变量作用域14.1. 常量 vs 全局变量 vs 静态变量 15. C类型转换16. 函数指针17. 悬空指针 vs 野指针18. 为什么使用空指针&#xff0c;建议使用nullptr而不是NULL&#xff1f; 11. C…

C++ 递归函数

一 递归函数 递归函数(Recursive Function&#xff09;即自调用函数&#xff0c;即在函数体内有直接或间接地自己调用自己的语句。 大多数递归函数都能够用非递归函数代替。 例如&#xff1a;求两个整数a,b的最大公约数。 算法描述&#xff1a; 大多数递归函数都能用非递归…

frp内网穿透服务搭建与使用

frp内网穿透服务搭建与使用 1、frp简介 frp 是一个专注于内网穿透的高性能的反向代理应用&#xff0c;支持 TCP、UDP、HTTP、HTTPS 等多种协议。 可以将内网服务以安全、便捷的方式通过具有公网 IP 节点的中转暴露到公网。frp工作原理 服务端运行&#xff0c;监听一个主端口…

经常发文章的你是否想过定时发布是咋实现的?

前言 可乐他们团队最近在做一个文章社区平台,由于人手不够,前后端都是由前端同学来写。后端使用 nest 来实现。 某一天周五下午,可乐正在快乐摸鱼,想到周末即将来临,十分开心。然而,产品突然找到了他,说道:可乐,我们要做一个文章定时发布功能。 现在我先为你解释一…

C语言常见的动态内存错误及几个经典笔试题以及c/c++内存开辟空间等的介绍

文章目录 前言一、常见的动态内存错误1. 对NULL指针的解引用操作2. 对动态开辟空间的越界访问3. 对非动态开辟内存使用free()4. 使用free释放一块动态开辟内存的一部分5. 对同一块动态内存多次释放6. 动态开辟内存忘记释放&#xff08;内存泄漏&#xff09; 二、几个经典笔试题…

自动驾驶学习1-超声波雷达

1、简介 超声波雷达&#xff1a;利用超声波测算距离的雷达传感器装置&#xff0c;通过发射、接收 40kHz、48kHz或 58kHz 频率的超声波&#xff0c;根据时间差测算出障碍物距离&#xff0c;当距离过近时触发报警装置发出警报声以提醒司机。 超声波&#xff1a;人耳所不能听到的…

【复杂网络】如何用简易通俗的方式快速理解什么是“相对重要节点挖掘”?

什么是相对重要节点&#xff1f; 一、相对重要节点的定义二、如何区分相对重要节点与重要节点&#xff1f;1. 相对重要性与节点相似性2. 识别相对重要节点的两个阶段第一阶段&#xff1a;个体重要性值的计算第二阶段&#xff1a;累积重要性值的计算 三、经典的相对重要节点挖掘…

护眼灯排名前十的品牌有哪几款?2024年主流的十大护眼灯品牌分享

在当今的教育环境中&#xff0c;学生们面临着相当沉重的学业压力。放学后&#xff0c;许多孩子便投入到无休止的作业之中&#xff0c;常常夜深人静时还未完成。作为家长&#xff0c;孩子的视力健康自然成为了我们心中的一块大石。夜间学习时&#xff0c;灯光的质量至关重要。标…

call, apply , bind 区别详解 及 实现购物车业务开发实例

call 方法&#xff1a; 原理 call 方法允许一个对象借用另一个对象的方法。通过 call&#xff0c;你可以指定某个函数运行时 this 指向的上下文。本质上&#xff0c;call 改变了函数运行时的作用域&#xff0c;它可以让我们借用一个已存 在的函数&#xff0c;而将函数体内的 th…

解决windows中的WS Llinux子系统(unbantu2204)访问网络失败问题?

一、问题描述 unbantu先前可以正常访问网络&#xff0c;后面用着用着发现上不了网了&#xff0c; 出现如下异常 Hmm. We’re having trouble finding that site.We can’t connect to the server at www.iqiyi.com.If you entered the right address, you can:Try again late…

每日一题 礼物的最大价值

题目描述 礼物的最大价值_牛客题霸_牛客网 解题思路 这是一个典型的动态规划问题。我们可以使用一个二维数组 dp[][] 来存储到达每个格子时可以获得的最大价值。状态转移方程为 dp[i][j] max(dp[i-1][j], dp[i][j-1]) grid[i][j]&#xff0c;表示到达当前格子的最大价值是从…

云原生之Docker篇第一章 Docker 概述与安装

&#x1f339;作者主页&#xff1a;青花锁 &#x1f339;简介&#xff1a;Java领域优质创作者&#x1f3c6;、Java微服务架构公号作者&#x1f604; &#x1f339;简历模板、学习资料、面试题库、技术互助 &#x1f339;文末获取联系方式 &#x1f4dd; 系列文章目录 云原生之…

76.网络游戏逆向分析与漏洞攻防-移动系统分析-分析角色移动产生的数据包

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 如果看不懂、不知道现在做的什么&#xff0c;那就跟着做完看效果&#xff0c;代码看不懂是正常的&#xff0c;只要会抄就行&#xff0c;抄着抄着就能懂了 内容…