图实验报告
闽
江
学
院
电
子
系
实 实
验
报 报
告 学生姓名:
班级: 学 学 号:
课程:算法与数据结构 一、 实验题目::图及其应用 一、
实验地点:实验楼 A210 二、
实验目得: . 熟练掌握图得两种存储结构(邻接矩阵与邻接表)得表示方法 . 掌握图得基本运算及应用 。
加深对图得理解,逐步培养解决实际问题得编程能力
三、
实验内容: 。
采用邻接表或邻接矩阵方式存储图,实现图得深度遍历与广度遍历; 、 用广度优先搜索方法找出从一顶点到另一顶点边数最少得路径; 。
图得存储结构得转换。
四、
实验环境( 使用得 软硬件): Visual C++集成开发环境 五、 实验步骤及操作 1。启动 VC++; 2、 新建工程/Win32 Console Application,选择输入位置:输入工程得名称:tu; 按“确定”按钮,选择“An Empty Project”,再按“完成”按钮, 3。新建文件/C++ Source File,选中“添加到工程得复选按钮”,输入文件名“1. cpp”,按“确定” 按钮,在显示得代码编辑区内输入如下得参考程序: #include 〈stdio.h> #include <stdlib。h〉 #define Infinity 1000 #define MAX 20
typedef struct{
int vexnum;
//顶点数目
int arcnum;
//弧数目
量向点顶//
;]XAM[sxev rahcﻩ 阵矩接邻//
;]XAM[]XAM[scra tniﻩ U 图向无,D图向有:类种得图//
;dnik rahcﻩ}MGraph; //图得建立 MGraph Creat_MGraph(){
MGraph G;
int i,j,k,w;
char v1,v2;
;)"n\!)U(图向无,)D(图向有(类种得图入输请"(ftnirpﻩ scanf("%c",&G。kind);
;)"n\!目数弧与目数点顶入输请"(ftnirpﻩ scanf("%d%d”,&G。vexnum,&G、arcnum);
;)(rahctegﻩ
printf("请输入各个顶点(abc)!\n");
for(i=0;i〈G。vexnum;i++)
ﻩ scanf(”%c",&G。vexs[i]);
getchar();
for(i=0;i<G.vexnum;i++){
)++j;munxev、G〈j;0=j(rofﻩ ﻩ
G.arcs[i][j]=Infinity;
}
for(i=0;i〈G。arcnum;i++){
printf("请输入第 (%d) 条弧得起始点与它得权重(ccd)!\n",i+1);
;)w&,2v&,1v&,”d%c%c%"(fnacsﻩﻩ
;)(rahctegﻩ
j=k=0;
while(G、vexs[j]!=v1) j++;
//起点
点终//
;++k )2v=!]k[sxev。G(elihwﻩﻩ ;w=]k[]j[scra、Gﻩﻩ
)"U"==dnik、G(fiﻩ
G、arcs[k][j]=w;
}ﻩ ;G nruterﻩ} int visited[MAX];
//标志数组,显示就是否遍历 //递归深度遍历调用函数 void DFS(MGraph G,int i){
;j tniﻩ visited[i]=1;
printf(”
%c
",G、vexs[i]);
)++j;munxev.G<j;0=j(rofﻩ
)ytinifnI〈]j[]i[scra.G&&]j[detisiv!(fiﻩ
;)j,G(SFDﻩﻩ} //深度遍历函数 void M_DFSTraverse(MGraph G){
;i tniﻩ printf(”深度遍历图结果如下:
\n");
for(i=0;i〈G。vexnum;i++)
visited[i]=0;
)++i;munxev。G<i;0=i(rofﻩ )]i[detisiv!(fiﻩﻩ
;)i,G(SFDﻩﻩ
printf("\n”);
}
ﻩﻩ//广度遍历函数 void M_BFSTraverse(MGraph G){
int i,j,k,Q[MAX],w;
j=k=0;
printf("广度遍历图结果如下: \n”);
for(i=0;i〈G。vexnum;i++)
visited[i]=0;
)++i;munxev、G<i;0=i(rofﻩ ﻩ if(!visited[i]){
ﻩ
visited[i]=1;
ﻩ
printf(”
%c
",G。vexs[i]);
;i=]++k[Qﻩﻩ ﻩﻩ while(j!=k){
ﻩ
;++jﻩ ﻩ
for(w=0;w〈G.vexnum;w++)
ﻩﻩ
if(!visited[w] && G、arcs[j][w]〈Infinity){
ﻩ ﻩ;1=]w[detisivﻩ ﻩﻩ
ﻩﻩ printf("
%c
”,G.vexs[w]);
ﻩ
Q[k++]=w;
ﻩ
ﻩ
}ﻩ
}ﻩﻩ
}
;)"n\"(ftnirpﻩ} //最小生成树函数,对无向图适用 void MiniSpanTree_PRIM(MGraph G,char u){
char adjvex[MAX];
int lowcost[MAX];
;nim,0=k,j,i tniﻩ ;)"n\
:为树成生小最得图"(ftnirpﻩ while(G。vexs[k]!=u) k++;
for(i=0;i〈G、vexnum;i++)
ﻩ if(i!=k){
adjvex[i]=u;
lowcost[i]=G。arcs[k][i];
}ﻩ lowcost[k]=0;
for(i=0;i<G、vexnum-1;i++){
;ytinifnI=nimﻩ
for(j=0;j<G.arcnum;j++)
ﻩ if(lowcost[j] && lowcost[j]<min){ ;]j[tsocwol=nimﻩﻩ ﻩ;j=kﻩ
}
printf("%c—-(%d)-—%c\n”,adjvex[k],lowcost[k],G、vexs[k]);
;0=]k[tsocwolﻩﻩ
)++j;munxev.G<j;0=j(rofﻩﻩ ﻩ
if(G.arcs[k][j]〈lowcost[j]){
ﻩ
adjvex[j]=G、vexs[k];
ﻩ
;]j[]k[scra、G=]j[tsocwolﻩ ﻩ
} ﻩ } } //求最短路径得函数,对有向图适用 void ShortestPath_DIJ(MGraph G,char u){
点得上径路短最志标,组数维二//
,]XAM[]XAM[P tniﻩ ﻩ D[MAX],
//记录最短路径得长度
径路短最得它得求否是就志标//
,]XAM[lanifﻩﻩ ﻩ i,j,v,w,v0,min;
;0=0vﻩ ;++0v )u=!]0v[sxev.G(elihwﻩ for(v=0;v〈G.vexnum;++v){
//初始化
;]v[]0v[scra。G=]v[Dﻩﻩ
final[v]=0;
)++w;munxev、G<w;0=w(rofﻩﻩ
;0=]w[]v[Pﻩﻩ
if(D[v]〈Infinity){
ﻩ P[v][v0]=1;
P[v][v]=1;
ﻩ }
}
D[v0]=0;final[v0]=1;
for(i=1;i<G、vexnum;i++){
//循环求出各个最短路径
;ytinifnI=nimﻩﻩ )w++;munxev。G<w;0=w(rofﻩﻩﻩ)]w[lanif!(fiﻩ ﻩ{)nim<]w[D(fiﻩ
;]w[D=nim
;w=vﻩ
}ﻩ
final[v]=1;
for(w=0;w<G。vexnum;w++)
ﻩ
径路短最改修//
{))]w[D<]w[]v[scra.G+nim( && ]w[lanif!(fiﻩ
;]w[]v[scra、G+nim=]w[Dﻩ
ﻩ
)++j;munxev.G〈j;0=j(rofﻩ ﻩﻩ
ﻩ
P[w][j]=P[v][j];
ﻩ;1=]w[]w[Pﻩ
} ﻩﻩ }ﻩ printf("从已知点到其她各点得最短路径为: \n");
)++v;munxev、G〈v;0=v(rofﻩ {)]v[lanif(fiﻩﻩ ﻩ
printf("%c-—%c 得最短路径长度为 %d ,路径为:”,u,G、vexs[v],D[v]);
ﻩ
)++w;munxev.G<w;0=w(rofﻩ ﻩ)]w[]v[P(fiﻩ
ﻩﻩ printf(”
%c
",G。vexs[w]);
printf("\n”);
}ﻩﻩ}
ﻩvoid main(){
;G hparGMﻩ
G=Creat_MGraph();
M_DFSTraverse(G);
M_BFSTraverse(G);
if(G、kind=="U")
MiniSpanTree_PRIM(G,'a");
//无向图就求它得最小生成树
esleﻩ
ShortestPath_DIJ(G,"a’);
//有向图就求它得最短路径 }
4、 按F7 键,或工具图标进行工程得建立,如有错误,根据错误显示区中得提示,改正错误,重新建立 应用程序; 5.按 Ctrl+F5 键,或工具图标进行工程得执行。
6、新建工程/Win32 Console Application,选择输入位置:输入工程得名称:图得存储结构转换; 按“确定”按钮,选择“An Empty Project”,再按“完成"按钮, 7.新建文件/C++ Source File,选中“添加到工程得复选按钮”,输入文件名“1。
cpp”,按“确定” 按钮,在显示得代码编辑区内输入如下得参考程序:
#include<stdio。h〉 #include<stdlib、h〉 #define MAX 5 #define INF 100000 int visit[MAX]={0}; typedef struct mgraph {
int edges[MAX][MAX];
int n,e; }MGraph; typedef struct node {
int adjvex;
struct node *nextarc; }ArcNode; typedef struct Vnode {
ArcNode *firstarc; }VNode; typedef struct algraph {
VNode adjlist[MAX];
int n,e; }ALGraph; void MtoAL(MGraph mg,ALGraph* &alg) {
int i,j,n=mg.n;
ArcNode *p;
alg=(ALGraph *)malloc(sizeof(ALGraph));
for(i=0;i<n;i++)
alg->adjlist[i]、firstarc=NULL;
for(i=0;i<n;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;
} } void ALtoM(ALGraph *alg,MGraph &mg) {
int i=0,n=alg-〉n;
ArcNode *p;
for(i=0;i〈n;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; } void PrintMGraph(MGraph mg) {
for(int i=0;i<MAX;i++)
{
for(int j=0;j〈MAX;j++)
printf(”%-3d",mg。edges[i][j]);
printf(”\n");
}
printf(”the num of edge is:%-3d\n”,mg。e);
printf("the num of vertex is:%-3d\n",mg、n); } void PrintALGraph(ALGraph* alg) {
for(int i=0;i〈MAX;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");
} } void main() {
MGraph mg;
ALGraph *alg;
mg、n=5;mg、e=6;
int path[MAX];
int a[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}};
int i,j;
for(i=0;i〈mg、n;i++)
for(int j=0;j<mg。n;j++)
mg、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)图得存储结构得转换
五、
实验总结及心得体会:
从一个顶点出发只能访问到它所在连通分量得各顶点、如果有回路存在,一个顶点被访问之后又可能沿回路回到该顶点,为了避免对同一个顶点多次访问,在遍历过程中必须记下已经访问过得顶点,通常利用一维辅助数组记录顶点被访问得情况、 六、
对本实验过程及方法、手段得改进建议:
报告评分: 指导教师签字:
批阅日期: