第7章-图-CAL-FENGHAI.-(YICAI)-Company One1第7章图实验图的基本操作及应用一、实验目的1、熟悉图的基本概念,理解图的各种类型2、掌握图的邻接矩阵、邻接表的表示方法3、掌握图的两种遍历方法4、加深理解图的最小生成树的基本思想。
5、掌握图的最小生成树的生成方法和实现算法6、加深对图的理解,熟悉图的实际应用二、实验内容(一)验证实验1、图的邻接矩阵表示(二)设计实验1、图的遍历问题案例描述:已知8个城市的交通路线图如下图1所示,从沈阳出发,要到其他7个城市推销产品。
给出到达每一个城市的一组城市顺序。
图1:8个城市的交通路线图设计方案:图的遍历有深度优先遍历和广度优先遍历两种算法。
在这里我们利用数据结构中图的邻接矩阵存储方式以及图的深度优先遍历的算法来解决该问题。
结构定义:typedef char vextype[LEN];typedef int edgetype;typedef struct{ vexntype vex[LEN];edgetype arc[VEXN][VEXN];int vexn,arcn;}Mgraph;2、某公司拟建一个局域网,需要连接6栋楼(0,1,2,3,4,5),其地理分布如下图2所示,各边上的权值代表楼宇间距离。
设计要求:根据下图中的楼宇分布,设计出布线造价最小的局域网络图,要求连接所有的顶点,并且总的布线费用最低。
实验提示:要想布线造价最小,可将图中各顶点间的距离看作其费用。
这样就可以用Prim算法构造一棵最小生成树来解决问题。
图2 图2的邻接矩阵运行时输入数据及运行结果显示如下:Input vexnum,arcnum:6,10V1,v2,w=0,1,6V1,v2,w=0,2,5V1,v2,w=0,5,1V1,v2,w=1,5,5V1,v2,w=1,3,3V1,v2,w=2,5,5V1,v2,w=2,4,2V1,v2,w=3,5,6V1,v2,w=3,4,6V1,v2,w=4,5,4输出最小生成树中的边及其权值如下:(0,5)1(5,4)4(4,2)2(5,1)5(1,3)3参考程序:(一)验证实验1、图的邻接矩阵表示实验程序:#include "Stdio.h"#include "Conio.h"#include"stdio.h"#define MaxNum 50 //图的最大顶点数设为50typedef char VexType[7]; //图的顶点类型设为字符数组,2个字符长度typedef int EdgeType; //弧(边)的权值设为整型typedef struct {VexType V[MaxNum]; //一维数组存储顶点信息EdgeType E[MaxNum][MaxNum]; //二维数组表示邻接矩阵,存储边的信息int n,e; //顶点数和边数}MGraph; //图类型定义int Locate(MGraph *G,char vex[]) //确定顶点在图G中的位置,即在G->V中的序{int i;for(i=0;i<G->n;i++)if(strcmp(G->V[i],vex)==0)return i;}void CreateGraph(MGraph *G){int i,j,k;char vex1[3],vex2[3];//保存输入的顶点printf("\n输入图的顶点数和边数(用逗号分隔):");scanf("%d,%d",&(G->n),&(G->e));//输入顶点数和边数printf("输入图的顶点信息(最长2个字符):");for (i=0;i<G->n;i++){/*G->V[i][0]=G->V[i][1]=0;*/scanf("\n%s",G->V[i]); //输入n个顶点的标识信息,建立顶点数组}for (i=0;i<G->n;i++)for (j=0;j<G->n;j++)G->E[i][j]=0; //对邻接矩阵元素进行初始化printf("\n输入图中每条边所依附的两个顶点的标识信息:");for (k=0;k<G->e;k++) //输入e条边{printf("\n输入第%d条边的第1个顶点:",k+1);scanf("%s",vex1);printf("输入第%d条边的第2个顶点:",k+1);scanf("%s",vex2);// scanf("%s\n%s",vex1,vex2);i=Locate(G,vex1);j=Locate(G,vex2);// scanf("\n%d,%d",&i,&j); //输入每条边所依附的顶点在二维数组中的下标,建立邻接矩阵G->E[i][j]=1; //如果同时输入G->E[j][i]=1;,则是建立无向图的邻接矩阵}}void PrintGraph(MGraph *G)//打印图的顶点和边的信息{int i,j;printf("\n图中顶点个数为:%d",G->n);printf("\n图中边数为:%d",G->e);printf("\n图中顶点为:");for (i=0;i<G->n;i++)printf("%c%c ",G->V[i][0],G->V[i][1]);printf("\n图中边为:");for(i=0;i<G->n;i++)for(j=0;j<G->n;j++)if(G->E[i][j])printf("[%c%c,%c%c] ",G->V[i][0], G->V[i][1], G->V[j][0], G->V[j][1]);}main(){MGraph mg;CreateGraph(&mg);PrintGraph(&mg);}(二)设计实验1、图的遍历问题案例描述:已知8个城市的交通路线图如下图1所示,从沈阳出发,要到其他7个城市推销产品。
给出到达每一个城市的一组城市顺序。
#define NULL 0#define VEXN 30 //顶点的最大个数#define LEN 10 //城市名称的最大长度#include <stdio.h>typedef char vexntype[LEN]; //顶点数据类型typedef int edgetype; //边数据类型typedef struct{vexntype vex[VEXN];edgetype arc[VEXN][VEXN];int vexn,arcn; //顶点个数和边数}Mgraph; //图的邻接矩阵表示结构int visit[VEXN]; //遍历标志数组Mgraph City_Graph(){int i,j,k;Mgraph G;printf("\n input vex number");scanf("%d",&G.vexn); //输入顶点数目printf("input edge numbef:");scanf("%d",&G.arcn); //输入总边数printf("input %d vex information such as Shenyang Beijing and soon:\n",G.vexn);for(i=0;i<G.vexn;i++)scanf("%s",&G.vex[i]);for(i=0;i<G.vexn;i++)for(j=0;j<G.vexn;j++)G.arc[i][j]=0;for(k=0;k<G.arcn;k++) //输入各顶点距离{printf("input edge %d such as i,j:",k+1);scanf("%d,%d",&i,&j);while(i<1||i>G.vexn||j<1||j>G.vexn) //输入各顶点距离{printf("Error vexn Number,input(i,j)again:");scanf("%d,%d",&i,&j);}G.arc[i-1][j-1]=1;G.arc[j-1][i-1]=1;}return G;}void DFS_G(Mgraph G,int i) //输出深度优先遍历序列{int j;printf("%s,",G.vex[i]);visit[i]=1;for(j=0;j<G.vexn;j++)if((G.arc[i][j]==1)&&(!visit[j]))DFS_G(G,j);}main(){Mgraph G;G=City_Graph(); //调用输入顶点和边的函数printf("\nDFS:\n"); //调用查询最短路径函数DFS_G(G,0);}运行测试:<输入>Input vex number:8Input edge number:9Input 8 vex information such as Shenyang Beijing and so on:沈阳北京天津大连营口鞍山抚顺丹东(输入:每一个顶点回车)Input edge1 such as i,j:1,2(在英文状态下输入)Input edge1 such as i,j:1,3Input edge1 such as i,j:2,3Input edge1 such as i,j:4,5Input edge1 such as i,j:5,6Input edge1 such as i,j:6,7Input edge1 such as i,j:7,8Input edge1 such as i,j:1,6Input edge1 such as i,j:1,7<输出>DFS:沈阳北京天津鞍山营口大连抚顺丹东2、某公司拟建一个局域网,需要连接6栋楼(0,1,2,3,4,5),其地理分布如下图2所示,各边上的权值代表楼宇间距离。