实验7图.docx
- 文档编号:3870228
- 上传时间:2022-11-26
- 格式:DOCX
- 页数:13
- 大小:103.29KB
实验7图.docx
《实验7图.docx》由会员分享,可在线阅读,更多相关《实验7图.docx(13页珍藏版)》请在冰豆网上搜索。
实验7图
实验七:
图的应用
班级B11522学号20114052222姓名马瑞君成绩
一、实验预备知识
1复习C中的全局变量的概念。
2复习图的邻接矩阵和邻接表两种存储方式。
3复习图的两种遍历方法和求图的最小生成树的方法。
二、实验目的
1掌握图的邻接矩阵和邻接表两种存储方法。
2掌握有关图的操作算法并用高级语言实现。
3熟悉图的构造算法,了解实际问题的求解效率与采用何种存储结构与算法有着密切联系。
4掌握图的两种搜索路径的遍历算法。
5掌握求图的最小生成树的普里姆算法和克鲁斯卡尔算法。
三、实验内容
1.创建给定的图,用邻接表或邻接矩阵进行存储。
2.对所创建的图进行深度和广度优先搜索遍历,给出遍历过程中的顶点序列。
3.求图的最小生成树,按构造顺序输出边的序列。
3.编写一个主函数,将上面函数连在一起,构成一个完整程序。
4.将实验源程序调试并运行。
四、实验要求
创建图,如图G1所示。
图1G1
●用邻接表存储结构时,可以自定义链表中结点的顺序,如单链表以结点的从小到大排列。
按自定义的结点顺序将图1的存储邻接表画出。
●注意标志数组visited[n+1]的定义和赋值。
●将顶点1作为起点。
五、存储结构图
图2G1存储结构图
六、程序代码
#include
#include
#defineMaxVertices100//假设包含100个顶点
#defineMaxWeight32767//不邻接时为32767,但输出时用"∞"
typedefstruct//包含权的邻接矩阵的的定义
{intVertices[MaxVertices];//顶点信息的数组
intEdge[MaxVertices][MaxVertices];//边的权信息的数组
intnumV;//当前的顶点数
intnumE;//当前的边数
}AdjMatrix;
voidmain()
{voidCreateGraph(AdjMatrix*G);
voidDispGraph(AdjMatrixG);
voidPrim(AdjMatrixG);//最小生成树的普里姆算法;
AdjMatrixG;
CreateGraph(&G);
DispGraph(G);
Prim(G);
}
voidCreateGraph(AdjMatrix*G)//图(带权)的产生函数(建立无(有)向图)
{intn,e,vi,vj,w,i,j;
printf("请输入图的顶点数和边数(以空格分隔):
");
scanf("%d%d",&n,&e);
G->numV=n;G->numE=e;
for(i=0;i for(j=0;j {if(i==j) G->Edge[i][j]=0; else G->Edge[i][j]=32767; } for(i=0;i for(i=0;i {printf("请输入第%d个顶点的信息(整型): ",i+1); scanf("%d",&G->Vertices[i]); } printf("\n"); for(i=0;i {printf("请输入边的信息i,j,w(以空格分隔): "); scanf("%d%d%d",&vi,&vj,&w);//建立有向图时只有此句 G->Edge[vi-1][vj-1]=w; G->Edge[vj-1][vi-1]=w;//建立均向图片时要此句 } } voidDispGraph(AdjMatrixG)//输出邻接矩阵的信息 {inti,j; printf("\n输出顶点的信息(整型): \n"); for(i=0;i printf("%8d",G.Vertices[i]); printf("\n输出邻接矩阵: \n"); printf(""); for(i=0;i printf("%8d",G.Vertices[i]); for(i=0;i {printf("\n%8d",i+1); for(j=0;j {if(G.Edge[i][j]==32767)//无边时值为32767,但输出时为了方便输出"∞" printf("%8s","∞"); else printf("%8d",G.Edge[i][j]); } printf("\n"); } } typedefstruct//定义最小生成树的带权边 {intbegin,end;//边的起点和终点 intweight;//边的权值 }MinSpanTree; voidPrim(AdjMatrixG)//最小生成树的普里姆算法 {intn,j,k,v,min,m; n=G.numV; MinSpanTreee,mintree[100];//mintree生成树数组 for(j=1;j {mintree[j-1].begin=1;//将1并入U中 mintree[j-1].end=j+1; mintree[j-1].weight=G.Edge[0][j]; } for(k=0;k {min=MaxWeight; for(j=k;j if(mintree[j].weight {min=mintree[j].weight;m=j;} e=mintree[m];mintree[m]=mintree[k];mintree[k]=e; v=mintree[k].end; for(j=k+1;j {intd=G.Edge[v-1][mintree[j].end-1]; if(d {mintree[j].weight=d; mintree[j].begin=v; } } } printf("最小生成树为: "); for(j=0;j printf("\ni=%d,j=%d,weight=%d",mintree[j].begin,mintree[j].end,mintree[j].weight); printf("\n"); } #include #include #defineMAX_VERTEX_NUM7 intvisit[MAX_VERTEX_NUM]; structArcCell { intadj; }; structMGraph { intvexs[MAX_VERTEX_NUM]; ArcCellarcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; intvexnum,arcnum; }; structQnode { intdata; structQnode*next; }; structLinkquene { structQnode*front; structQnode*rear; }; structclosedge { intadjvex; intlowcost; }closedge[MAX_VERTEX_NUM]; intQueneEmpty(LinkqueneQ)//判断队为空 { if(Q.front==Q.rear) return0; else return1; } voidinitQuene(Linkquene&Q)//初始化队列 { Q.front=Q.rear=(Qnode*)malloc(sizeof(Qnode)); if(! Q.front) exit(0); Q.front->next=NULL; } voidEnquene(Linkquene&Q,inte)//入队 { Qnode*p=(Qnode*)malloc(sizeof(Qnode)); if(! p) exit(0); p->data=e; p->next=NULL; Q.rear->next=p; Q.rear=p; } voidDequene(Linkquene&Q,int&e)//出队 { Qnode*p=(Qnode*)malloc(sizeof(Qnode)); if(Q.front==Q.rear) exit(0); p=Q.front->next; e=p->data; Q.front->next=p->next; if(Q.rear==p) Q.rear=Q.front; } intLocateVex(MGraphG,intv1)//查找 { inti; for(i=0;i if(G.vexs[i]==v1) returni; return-1; } voidCreatUDN(MGraph&G)//创建无向图 { inti,j,k; printf("+++++++++++创建无向图++++++++++++++\n"); printf("请输入图G顶点和弧个数: "); scanf("%d%d",&G.vexnum,&G.arcnum); printf("请依次输入顶点: "); for(i=0;i scanf("%d",&G.vexs[i]); for(i=0;i for(j=0;j G.arcs[i][j].adj=10000; for(k=0;k { intv1,v2,w; printf("请输入一条边依附的顶点和权值: "); scanf("%d%d%d",&v1,&v2,&w);//输入一条边依附的两点及权值 i=LocateVex(G,v1);//确定顶点V1和V2在图中的位置 j=LocateVex(G,v2); G.arcs[i][j].adj=w; G.arcs[j][i].adj=G.arcs[i][j].adj; } printf("图G邻接矩阵创建成功! \n"); } intFirstAdjVex(MGraphG,intv)//返回依附顶点v的第一个点 { for(intj=0;j { if(G.arcs[v][j].adj! =10000) { returnj; break; } } return-1; } intNextAdjVex(MGraphG,intv,intw)//返回依附顶点V的相对于W的下一个顶点 { for(intj=0;j { if(G.arcs[v][j].adj! =10000&&j>w) { returnj; break; } } return-1; } voidDFS(MGraphG,intv) { intw; visit[v]=1; printf("%d",G.vexs[v]); for(w=FirstAdjVex(G,v);w>=0;w=NextAdjVex(G,v,w)) { if(! visit[w]) DFS(G,w); } } voidDFSTraverse(MGraphG)//深度遍历 { intv; for(v=0;v visit[v]=0; for(v=0;v if(! visit[v]) DFS(G,v); } voidBFSTraverse(MGraphG)//广度遍历 { intm,w; LinkqueneQ; for(intv=0;v visit[v]=0; initQuene(Q); for(v=0;v { if(! visit[v]) { visit[v]=1; Enquene(Q,v); printf("%d",G.vexs[v]); while(QueneEmpty(Q)==1) { Dequene(Q,m); for(w=FirstAdjVex(G,m);w>=0;w=NextAdjVex(G,m,w)) { if(! visit[w]) { visit[w]=1; printf("%d",G.vexs[w]); Enquene(Q,w); } } } } } } voidmain() { MGraphG; CreatUDN(G); printf("广度优先遍历结果为: "); DFSTraverse(G); printf("\n"); printf("深度优先遍历结果为: "); BFSTraverse(G); printf("\n"); } 七、运行结果 1.将输入、输出结果抓图 2.画出最小生成树的图(自己可以和运行的结果比对一下) 八、实验总结 实验过程中遇到的问题及解决方法,收获。 在主函数中要求输入需要构建的图的顶点数和边数,调用构建函数,分别用两个for语句来构建图(即输入顶点的值和边的权值),此处要求输入有一定的顺序,不能随意输入。 本函数通过传过来的对象G得到相关数组,通过for循环来分别输出顶点数组和边的权值数组(邻接矩阵)。 通过两个for循环来查找各顶点,判断其是否有边(权值),有边的话又有几条边,每找到一条边则度数加一,记录到存放顶点的度数的数组M[]中,搜索完成后输出各顶点的度。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实验