图实验报告.docx
《图实验报告.docx》由会员分享,可在线阅读,更多相关《图实验报告.docx(15页珍藏版)》请在冰豆网上搜索。
图实验报告
闽江学院电子系
实验报告
学生姓名:
班级:
学号:
课程:
算法与数据结构
一、实验题目:
:
图及其应用
一、实验地点:
实验楼A210
二、实验目的:
.熟练掌握图的两种存储结构(邻接矩阵和邻接表)的表示方法
.掌握图的基本运算及应用
.加深对图的理解,逐步培养解决实际问题的编程能力
三、实验内容:
.采用邻接表或邻接矩阵方式存储图,实现图的深度遍历和广度遍历;
.用广度优先搜索方法找出从一顶点到另一顶点边数最少的路径;
.图的存储结构的转换。
四、实验环境(使用的软硬件):
VisualC++集成开发环境
五、实验步骤及操作
1.启动VC++;
2.新建工程/Win32ConsoleApplication,选择输入位置:
输入工程的名称:
tu;
按“确定”按钮,选择“AnEmptyProject”,再按“完成”按钮,
3.新建文件/C++SourceFile,选中“添加到工程的复选按钮”,输入文件名“1.cpp”,按“确定”
按钮,在显示的代码编辑区内输入如下的参考程序:
#include
#include
#defineInfinity1000
#defineMAX20
typedefstruct{
intvexnum;//顶点数目
intarcnum;//弧数目
charvexs[MAX];//顶点向量
intarcs[MAX][MAX];//邻接矩阵
charkind;//图的种类:
有向图D,无向图U
}MGraph;
//图的建立
MGraphCreat_MGraph(){
MGraphG;
inti,j,k,w;
charv1,v2;
printf("请输入图的种类(有向图(D),无向图(U)!
\n");
scanf("%c",&G.kind);
printf("请输入顶点数目和弧数目!
\n");
scanf("%d%d",&G.vexnum,&G.arcnum);
getchar();
printf("请输入各个顶点(abc)!
\n");
for(i=0;iscanf("%c",&G.vexs[i]);
getchar();
for(i=0;ifor(j=0;jG.arcs[i][j]=Infinity;
}
for(i=0;iprintf("请输入第(%d)条弧的起始点和它的权重(ccd)!
\n",i+1);
scanf("%c%c%d",&v1,&v2,&w);
getchar();
j=k=0;
while(G.vexs[j]!
=v1)j++;//起点
while(G.vexs[k]!
=v2)k++;//终点
G.arcs[j][k]=w;
if(G.kind=='U')
G.arcs[k][j]=w;
}
returnG;
}
intvisited[MAX];//标志数组,显示是否遍历
//递归深度遍历调用函数
voidDFS(MGraphG,inti){
intj;
visited[i]=1;
printf("%c",G.vexs[i]);
for(j=0;jif(!
visited[j]&&G.arcs[i][j]DFS(G,j);
}
//深度遍历函数
voidM_DFSTraverse(MGraphG){
inti;
printf("深度遍历图结果如下:
\n");
for(i=0;ivisited[i]=0;
for(i=0;iif(!
visited[i])
DFS(G,i);
printf("\n");
}
//广度遍历函数
voidM_BFSTraverse(MGraphG){
inti,j,k,Q[MAX],w;
j=k=0;
printf("广度遍历图结果如下:
\n");
for(i=0;ivisited[i]=0;
for(i=0;iif(!
visited[i]){
visited[i]=1;
printf("%c",G.vexs[i]);
Q[k++]=i;
while(j!
=k){
j++;
for(w=0;wif(!
visited[w]&&G.arcs[j][w]visited[w]=1;
printf("%c",G.vexs[w]);
Q[k++]=w;
}
}
}
printf("\n");
}
//最小生成树函数,对无向图适用
voidMiniSpanTree_PRIM(MGraphG,charu){
charadjvex[MAX];
intlowcost[MAX];
inti,j,k=0,min;
printf("图的最小生成树为:
\n");
while(G.vexs[k]!
=u)k++;
for(i=0;iif(i!
=k){
adjvex[i]=u;
lowcost[i]=G.arcs[k][i];
}
lowcost[k]=0;
for(i=0;imin=Infinity;
for(j=0;jif(lowcost[j]&&lowcost[j]min=lowcost[j];
k=j;
}
printf("%c--(%d)--%c\n",adjvex[k],lowcost[k],G.vexs[k]);
lowcost[k]=0;
for(j=0;jif(G.arcs[k][j]adjvex[j]=G.vexs[k];
lowcost[j]=G.arcs[k][j];
}
}
}
//求最短路径的函数,对有向图适用
voidShortestPath_DIJ(MGraphG,charu){
intP[MAX][MAX],//二维数组,标志最短路径上的点
D[MAX],//记录最短路径的长度
final[MAX],//标志是否求的它的最短路径
i,j,v,w,v0,min;
v0=0;
while(G.vexs[v0]!
=u)v0++;
for(v=0;vD[v]=G.arcs[v0][v];
final[v]=0;
for(w=0;wP[v][w]=0;
if(D[v]P[v][v0]=1;P[v][v]=1;
}
}
D[v0]=0;final[v0]=1;
for(i=1;imin=Infinity;
for(w=0;wif(!
final[w])
if(D[w]v=w;min=D[w];
}
final[v]=1;
for(w=0;wif(!
final[w]&&(min+G.arcs[v][w]D[w]=min+G.arcs[v][w];
for(j=0;jP[w][j]=P[v][j];
P[w][w]=1;
}
}
printf("从已知点到其他各点的最短路径为:
\n");
for(v=0;vif(final[v]){
printf("%c--%c的最短路径长度为%d,路径为:
",u,G.vexs[v],D[v]);
for(w=0;wif(P[v][w])
printf("%c",G.vexs[w]);
printf("\n");
}
}
voidmain(){
MGraphG;
G=Creat_MGraph();
M_DFSTraverse(G);
M_BFSTraverse(G);
if(G.kind=='U')
MiniSpanTree_PRIM(G,'a');//无向图就求它的最小生成树
else
ShortestPath_DIJ(G,'a');//有向图就求它的最短路径
}
4.按F7键,或工具图标进行工程的建立,如有错误,根据错误显示区中的提示,改正错误,重新建立
应用程序;
5.按Ctrl+F5键,或工具图标进行工程的执行。
6.新建工程/Win32ConsoleApplication,选择输入位置:
输入工程的名称:
图的存储结构转换;
按“确定”按钮,选择“AnEmptyProject”,再按“完成”按钮,
7.新建文件/C++SourceFile,选中“添加到工程的复选按钮”,输入文件名“1.cpp”,按“确定”
按钮,在显示的代码编辑区内输入如下的参考程序:
#include
#include
#defineMAX5
#defineINF100000
intvisit[MAX]={0};
typedefstructmgraph
{
intedges[MAX][MAX];
intn,e;
}MGraph;
typedefstructnode
{
intadjvex;
structnode*nextarc;
}ArcNode;
typedefstructVnode
{
ArcNode*firstarc;
}VNode;
typedefstructalgraph
{
VNodeadjlist[MAX];
intn,e;
}ALGraph;
voidMtoAL(MGraphmg,ALGraph*&alg)
{
inti,j,n=mg.n;
ArcNode*p;
alg=(ALGraph*)malloc(sizeof(ALGraph));
for(i=0;ialg->adjlist[i].firstarc=NULL;
for(i=0;i{
for(j=n-1;j>=0;j--)
{
if(mg.edges[i][j]!
=0)
{
p=(ArcNode*)malloc(sizeof(ArcNode));
p->adjvex=j;
p->nextarc=alg->adjlist[i].firstarc;
alg->adjlist[i].firstarc=p;
}
}
alg->n=mg.n;
alg->e=mg.e;
}
}
voidALtoM(ALGraph*alg,MGraph&mg)
{
inti=0,n=alg->n;
ArcNode*p;
for(i=0;i{
p=alg->adjlist[i].firstarc;
while(p)
{
mg.edges[i][p->adjvex]=1;
p=p->nextarc;
}
}
mg.n=alg->n;
mg.e=alg->e;
}
voidPrintMGraph(MGraphmg)
{
for(inti=0;i{
for(intj=0;jprintf("%-3d",mg.edges[i][j]);
printf("\n");
}
printf("thenumofedgeis:
%-3d\n",mg.e);
printf("thenumofvertexis:
%-3d\n",mg.n);
}
voidPrintALGraph(ALGraph*alg)
{
for(inti=0;i{
if(alg->adjlist[i].firstarc)
{
printf("vertex[%d]:
",i);
ArcNode*p=alg->adjlist[i].firstarc;
while(p)
{
printf("%-3d",p->adjvex);
p=p->nextarc;
}
}
printf("\n");
}
}
voidmain()
{
MGraphmg;
ALGraph*alg;
mg.n=5;mg.e=6;
intpath[MAX];
inta[MAX][MAX]={{0,1,0,1,0},{1,0,1,0,0},{0,1,0,1,1},{1,0,1,0,1},{0,0,1,1,0}};
inti,j;
for(i=0;ifor(intj=0;jmg.edges[i][j]=a[i][j];
printf("邻接矩阵表示图:
\n");
PrintMGraph(mg);
MtoAL(mg,alg);
printf("转化为邻接表表示图:
\n");
PrintALGraph(alg);
ALtoM(alg,mg);
printf("转化为邻接矩阵表示图:
\n");
PrintMGraph(mg);
}
8.按F7键,或工具图标进行工程的建立,如有错误,根据错误显示区中的提示,改正错误,重新建立
应用程序;
9.按Ctrl+F5键,或工具图标进行工程的执行。
六、实验结果:
(1)无向图
(2)有向图
(3)图的存储结构的转换
五、实验总结及心得体会:
从一个顶点出发只能访问到它所在连通分量的各顶点。
如果有回路存在,一个顶点被访问之后又可能沿回路回到该顶点,为了避免对同一个顶点多次访问,在遍历过程中必须记下已经访问过的顶点,通常利用一维辅助数组记录顶点被访问的情况。
六、对本实验过程及方法、手段的改进建议:
报告评分:
指导教师签字:
批阅日期: