本关任务:要求从文件输入顶点和边数据,包括顶点信息、边、权值等,编写程序实现以下功能。 1)构造无向网G的邻接矩阵和顶点集,即图的存储结构为邻接矩阵。 2)输出无向网G的各顶点和邻接矩阵。 3)输出无向网G中顶点H的所有邻接顶点。
图是表达“多对多”的关系的一种数据结构,由非空的有限顶点集合和有限边集合组成。将图的类型定义为枚举类型,在枚举值表中罗列:
enum GraphKind{DG,DN,UDG,UDN}; // 有向图,有向网,无向图,无向网
每个顶点数据类型为VertexType,一个图的顶点集合用数组表示,数组下标表示顶点位置。数组内容包含顶点的信息,图的顶点集合的数据类型定义如下:
#define MAX_VERTEX_NUM 20 // 最大顶点个数typedef char VertexType[16]; // 顶点类型VertexType vexs[MAX_VERTEX_NUM]; // 顶点向量将顶点数据类型定义为长度为16的字符数组类型,可以将表示的城市名称存储在计算机中。
邻接矩阵是表示顶点之间相邻关系的矩阵。设G=(V,E)是具有n顶点的图,则G的邻接矩阵是具有如下性质的n阶方阵:


用邻接矩阵来表示一个具有n个顶点的图时,用邻接矩阵中的n×n个元素存储顶点间相邻关系,对于无权图,当邻接矩阵中的元素仅表示相应的边是否存在时,VRType可定义为值为0和1的枚举类型,0表示两个顶点之间没有边,即没有关系。对于带权图,则为权值,如果两个顶点之间没有边,则用一个很大很大的数代替∞。将顶点关系类型VRType定义为整型:
typedef int VRType; // 顶点关系边的数据类型
顶点关系边的数据类型类型,对于无权图,用1或0表示相邻否;对于带权图,则为权值。
图的边集合的数据类型定义如下:
#define INFINITY INT_MAX // 用整型最大值代替∞typedef struct{VRType adj; } ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; 说明: AcrCell和AdjMatrix都是类型的名称,若有定义: AdjMatrix arcs; 则arcs是一个以元素类型为AcrCell的20*20二维数组。上述声明与下面等同: ArcCell arcs [MAX_VERTEX_NUM][MAX_VERTEX_NUM];
图的邻接矩阵存储表示,类型定义如下:
struct MGraph{VertexType vexs[MAX_VERTEX_NUM]; // 顶点向量AdjMatrix arcs; // 邻接矩阵int vexnum, arcnum; // 图的当前顶点数和弧数GraphKind kind; // 图的种类标志};图的邻接矩阵表示法是图的一种顺序存储结构,优点是可以快速判断两个顶点之间是否存在边,可以快速添加边或者删除边,可以快速计算顶点度数、求邻接点的操作等;而其缺点是如果顶点之间的边比较少,会比较浪费空间。
邻接矩阵具有如下性质: (1)图中各项点的序号确定后,图的邻接矩阵是唯一确定的; (2)无向图和无向网的邻接矩阵是一个对称矩阵; (3)无向图邻接矩阵中第i行(或第i列)的非0元素的个数即为第i个顶点的度; (4)有向图邻接矩阵中第i行非0元素的个数为第i个顶点的出度,第i列非0元素的个数为第i个顶点的入度,第i个顶点的度为第i行与第j非0元素个数之和; (5)无向图的边数等于邻接矩阵中非0元素个数之和的一半,有向图的弧数等于邻接矩阵中非0元素个数之和。
根据提示,在右侧编辑器补充代码,要求从文件中输入顶点和边数据,包括顶点信息、边、权值等,编写函数实现图的基本运算:
void CreateGraphF(MGraph &G);// 采用数组(邻接矩阵)表示法,由文件构造无向网Gvoid Display(MGraph G); // 输出邻接矩阵存储表示的图Gint LocateVex(MGraph G,VertexType u);//若G中存在顶点u,则返回该顶点在图中位置;否则返回-1 VertexType& GetVex(MGraph G,int v); // v是G中某个顶点的序号,返回v的值int FirstAdjVex(MGraph G,VertexType v);//v是图G中某个顶点,返回v的第一个邻接顶点的序号。若顶点在G中没有邻接顶点,则返回-1 int NextAdjVex(MGraph G,VertexType v,VertexType w);//v是G中某个顶点,w是v的邻接顶点,返回v的(相对于w的)下一个邻接顶点的序号,若w是v的最后一个邻接顶点,则返回-1 void DestroyGraph(MGraph &G); // 销毁图G 平台会对你编写的代码进行测试:
测试输入: 3 lt.txt 武汉
输入说明: 第一行输入
3,表示输入图的类型为无向网。 第二行输入文件名,该文件里保存了图的数据信息,内容如下: 6 9 武汉 上海 长沙 南京 成都 广州 武汉 长沙 9 武汉 成都 2 长沙 上海 2 长沙 南京 2 上海 南京 5 上海 广州 4 上海 成都 3 南京 广州 8 成都 广州 6
第1行为图的顶点的个数n; 第2行为图的边的条数m; 第3行至第n+2行是n个顶点的数据; 第n+3行至第n+m+2行是m条边的数据; 最后输入一个顶点的数据
预期输出: 无向网 6个顶点9条边。顶点依次是: 武汉 上海 长沙 南京 成都 广州 图的邻接矩阵: ∞ ∞ 9 ∞ 2 ∞ ∞ ∞ 2 5 ∞ ∞ 9 2 ∞ 2 ∞ ∞ ∞ 5 2 ∞ ∞ ∞ 2 ∞ ∞ ∞ ∞ ∞ ∞ ∞ ∞ ∞ ∞ ∞ 长沙 成都
- #include
- #include
- #include
- #include
-
- typedef int VRType; // 顶点关系类型
- typedef char VertexType[20]; // 顶点类型
- // 图的数组(邻接矩阵)存储表示
- #define INFINITY INT_MAX // 用整型最大值代替∞
- #define MAX_VERTEX_NUM 20 // 最大顶点个数
- typedef enum{DG,DN,UDG,UDN}GraphKind; // {有向图,有向网,无向图,无向网}
-
- typedef struct
- {
- VRType adj; // 顶点关系类型。对无权图,用1(是)或0(否)表示相邻否;对带权图,则为权值
- }ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; // 二维数组
-
- typedef struct // 图的数组(邻接矩阵)存储
- {
- VertexType vexs[MAX_VERTEX_NUM]; // 顶点向量
- AdjMatrix arcs; // 邻接矩阵
- int vexnum,arcnum; // 图的当前顶点数和弧数
- GraphKind kind; // 图的种类标志
- }MGraph;
-
- void visit(VertexType i);
-
- void CreateGraphF(MGraph &G);// 采用数组(邻接矩阵)表示法,由文件构造无向网G
- void Display(MGraph G); // 输出邻接矩阵存储表示的图G
- int LocateVex(MGraph G,VertexType u);//若G中存在顶点u,则返回该顶点在图中位置;否则返回-1
- VertexType* GetVex(MGraph G,int v); // v是G中某个顶点的序号,返回v的值
- int FirstAdjVex(MGraph G,VertexType v);//v是图G中某个顶点,返回v的第一个邻接顶点的序号。若顶点在G中没有邻接顶点,则返回-1
- int NextAdjVex(MGraph G,VertexType v,VertexType w);//v是G中某个顶点,w是v的邻接顶点,返回v的(相对于w的)下一个邻接顶点的序号,若w是v的最后一个邻接顶点,则返回-1
- void DestroyGraph(MGraph &G); // 销毁图G
-
-
-
-
- int main()
- {
- MGraph g;
- VertexType v1,v2;
- CreateGraphF(g); // 利用数据文件创建邻接矩阵表示的图
- Display(g); // 输出图
- int i,j,k,n;
- //printf("请输入顶点的值: ");
- scanf("%s",v1);
- //printf("输出图G中顶点%s的所有邻接顶点: ",v1);
- k=FirstAdjVex(g,v1);
- while(k!=-1)
- {
- strcpy(v2, g.vexs[k] );
- visit(v2);
- k=NextAdjVex(g,v1,v2);
- }
- printf("\n");
- return 0;
- }
-
- void visit(VertexType i)
- {
- printf("%s ",i);
- }
-
-
- void CreateGraphF(MGraph &G)
- {
- // 采用数组(邻接矩阵)表示法,由文件构造无向网G
- /********** Begin **********/
- int i,j,k,w;
- char filename[13];
- VertexType va,vb;
- FILE * graphlist;
- scanf("%d",&G.kind);
- scanf("%s",filename);
- graphlist=fopen(filename,"r");
-
- fscanf(graphlist,"%d",&G.vexnum);
- fscanf(graphlist,"%d",&G.arcnum);
- for(i=0;i
- fscanf(graphlist,"%s",G.vexs[i]);
- for(i=0;i
- for(j=0;j
- if(G.kind%2)
- G.arcs[i][j].adj=INFINITY;
- else
- G.arcs[i][j].adj=0;
- }
- for(k=0;k
- if(G.kind%2)
- fscanf(graphlist,"%s%s%d",va,vb,&w);
- else
- fscanf(graphlist,"%s%s",va,vb);
- i=LocateVex(G,va);
- j=LocateVex(G,vb);
- if(G.kind==0)
- G.arcs[i][j].adj=1;
- else if(G.kind==1)
- G.arcs[i][j].adj=w;
- else if(G.kind==2)
- G.arcs[i][j].adj=G.arcs[j][i].adj=1;
- else
- G.arcs[i][j].adj=G.arcs[j][i].adj=w;
- }
- fclose(graphlist);
- /********** End **********/
- }
-
-
- void Display(MGraph G)
- {
- // 输出邻接矩阵存储表示的图G
- /********** Begin **********/
- int i,j;
- switch(G.kind){
- case DG:printf("有向图\n");break;
- case DN:printf("有向网\n");break;
- case UDG:printf("无向图\n");break;
- case UDN:printf("无向网\n");
- }
- printf("%d个顶点%d条边。顶点依次是: ",G.vexnum,G.arcnum);
- for(i=0;i
- printf("%s ",G.vexs[i]);
- printf("\n图的邻接矩阵:\n");
- for(i=0;i
- for(j=0;j
- if(G.kind%2){
- if(G.arcs[i][j].adj==INFINITY)
- printf("%s\t","∞");
- else
- printf("%d\t",G.arcs[i][j].adj);
- }else
- printf("%d\t",G.arcs[i][j].adj);
- printf("\n");
- }
- /********** End **********/
- }
-
-
- int LocateVex(MGraph G,VertexType u)
- {
- //初始条件:图G存在,u和G中顶点有相同特征
- // 操作结果:若G中存在顶点u,则返回该顶点在图中位置;否则返回-1
- /********** Begin **********/
- int i;
- for(i=0;i
- if(strcmp(u,G.vexs[i])==0) return i;
- return -1;
- /********** Begin **********/
- }
-
- VertexType* GetVex(MGraph G,int v)
- {
- // 初始条件:图G存在,v是G中某个顶点的序号。操作结果:返回v的值
- /********** Begin **********/
- if(v>=G.vexnum || v<0)
- exit(0);
- return &(G.vexs[v]);
- /********** End **********/
- }
-
-
-
- int FirstAdjVex(MGraph G,VertexType v)
- {
- // 初始条件:图G存在,v是G中某个顶点
- // 操作结果:返回v的第一个邻接顶点的序号。若顶点在G中没有邻接顶点,则返回-1
- /********** Begin **********/
- int i,j,k;
- if(G.kind%2)
- j=INFINITY;
- else
- j=0;
- k=LocateVex(G,v);
- for(i=0;i
- if(G.arcs[k][i].adj!=j)
- return i;
- return -1;
- /********** End **********/
- }
-
- int NextAdjVex(MGraph G,VertexType v,VertexType w)
- {
- // 初始条件:图G存在,v是G中某个顶点,w是v的邻接顶点
- // 操作结果:返回v的(相对于w的)下一个邻接顶点的序号,若w是v的最后一个邻接顶点,则返回-1
- /********** Begin **********/
- int i,j,k1,k2;
- if(G.kind%2)
- j=INFINITY;
- else
- j=0;
- k1=LocateVex(G,v);
-
- k2=LocateVex(G,w);
-
- for(i=k2+1;i
- if(G.arcs[k1][i].adj!=j)
- return i;
- return -1;
- /********** End **********/
- }
-
-
- void DestroyGraph(MGraph &G)
- { // 初始条件:图G存在。操作结果:销毁图G
- /********** Begin **********/
- int i,j,k=0;
- if(G.kind%2)
- k=INFINITY;
- G.vexnum=0;
- G.arcnum=0;
- /********** End **********/
- }
-
输出说明: 第一行输出图的类型。 第二行起输出图的顶点和边的数据信息。 最后一行输出输入顶点的所有邻接点。
-
相关阅读:
node的web编程
(C语言)成绩统计
CPSC认证是什么意思?CPSC主要测什么?
【Mycat】Mycat主从复制
在express中使用session认证
【POST请求-腾讯翻译君-爬虫案例】
QCSPCChart for Java R3x0 Crack
Unity技术手册 - 干扰/噪音/杂波(Noise)子模块
刷完HashMap源码,我们一起进大厂
2024Java springboot mybatis-flex 根据数据表时间开启定时任务
-
原文地址:https://blog.csdn.net/toptopniba/article/details/134534404