CSU算法分析与设计实验报告.docx
《CSU算法分析与设计实验报告.docx》由会员分享,可在线阅读,更多相关《CSU算法分析与设计实验报告.docx(32页珍藏版)》请在冰豆网上搜索。
CSU算法分析与设计实验报告
算法分析与设计实验报告
学院:
信息科学与工程学院
专业:
学号:
姓名:
指导老师:
2010年1月7日
(一)BFS-basedshortestpathWriteaBFS-based
运行方法:
建立c:
\graph.txt,里面保存的是用于构建图的信息。
我测试程序时输入的图如下:
12
13
24
25
38
58
46
57
图形表示该图为
图1.1
下面找出1-8之间的最短路径:
下面是7-8之间的最短路径:
自己观察图可知,以上两组源结点与目标结点之间的路径不止一条,上面显示的确实是最短路径。
测试正确。
程序重要的是要构建正确的结点的结构。
源程序:
#include
#include
#defineMAX_VEXVALUE_NUM50
enumCOLOR{white=1,grey,black};
typedefstructNODE
{
intdepth;//结点被访问的深度
intvex_value;//结点表示的值
COLORcolor;
structNODE*pre;//指向父母节点
}NODE;
typedefstruct
{
NODEvexs[MAX_VEXVALUE_NUM];//结点
intvexnum;//图中结点数
intgraph[MAX_VEXVALUE_NUM][MAX_VEXVALUE_NUM];//邻接矩阵
}Graph;
boolvisited[MAX_VEXVALUE_NUM];//访问标识
voidreadGraph(Graph&gra);
voidprintGraph(Graph&gra);
voidshortestPath(Graph&G,NODEsource,NODEdest);
intlocate(GraphG,NODEvex);//确定结点vex的在矩阵中的位置
intlocateByVexvalue(GraphG,intval);//根据结点中的数确定在邻接矩阵呢中的位置
intmain(intargv,char*argc[])
{
Graphg;
inti;
NODEs,d;
readGraph(g);
printGraph(g);
intsource,dest;
printf("**************求最短路径***************\n");
printf("请输入源结点:
");
scanf("%d",&source);
printf("请输入目的结点:
");
fflush(stdin);
scanf("%d",&dest);
fflush(stdin);
for(i=0;i{
if(source==g.vexs[i].vex_value)
{
s=g.vexs[i];
break;
}
}
for(i=0;i{
if(dest==g.vexs[i].vex_value)
{
d=g.vexs[i];
break;
}
}
shortestPath(g,s,d);
printf("最短路径长度为:
%d\n",g.vexs[i].depth);
NODE*p=&g.vexs[i];
inttemp[MAX_VEXVALUE_NUM];//暂时存放最短路径结点,使结点逆向输出,即按照遍历方向输出
inttemp_len=0;
while(p!
=NULL)
{
temp[temp_len]=p->vex_value;
++temp_len;
p=p->pre;
}
printf("最短路径为:
");
for(;temp_len>0;--temp_len)
printf("%d,",temp[temp_len-1]);
printf("\n");
return0;
}
voidreadGraph(Graph&gra)//读取文件,构造一个图
{
intv1,v2;
inti,j;
FILE*fp;
if(!
(fp=fopen("c:
\\graph.txt","r")))
{
perror("不能打开文件!
");
exit(-1);
}
gra.vexnum=0;
while(!
feof(fp))//反复读取文件知道文件结束
{
fscanf(fp,"%d%d",&v1,&v2);
for(i=0;i{
if(v1==gra.vexs[i].vex_value)
break;
}
if(i==gra.vexnum)
{
gra.vexs[gra.vexnum].vex_value=v1;
++gra.vexnum;
}
for(i=0;i{
if(v2==gra.vexs[i].vex_value)
break;
}
if(i==gra.vexnum)
{
gra.vexs[gra.vexnum].vex_value=v2;
++gra.vexnum;
}
}
printf("图中共有%d个节点\n节点为:
",gra.vexnum);
for(i=0;i{
gra.vexs[i].color=white;
gra.vexs[i].depth=0;
gra.vexs[i].pre=NULL;
}
for(i=0;iprintf("%d,%d\n",gra.vexs[i].vex_value,gra.vexs[i].color);
printf("\n");
for(i=0;ifor(j=0;j{
gra.graph[i][j]=0;
}
fseek(fp,SEEK_SET,0);
while(!
(feof(fp)))//第二次读取文件,获取输入边的信息
{
fscanf(fp,"%d%d",&v1,&v2);
i=locateByVexvalue(gra,v1);j=locateByVexvalue(gra,v2);
gra.graph[j][i]=gra.graph[i][j]=1;
}
fclose(fp);
}
voidprintGraph(Graph&gra)//以邻接表形式打印图中各个结点
{
inti;
for(i=0;i{
for(intj=0;jprintf("%d",gra.graph[i][j]);
printf("\n");
}
for(i=0;i{
printf("%d--",gra.vexs[i].vex_value);//由邻接矩阵的索引确定在该行的元素
for(intj=0;j{
if(gra.graph[i][j]!
=0)
printf("%d,",gra.vexs[j].vex_value);
}
printf("\n");
}
}
typedefstructQueue//访问队列
{
intvex[MAX_VEXVALUE_NUM];
intlength;
}Queue;
voidInitQueue(Queue&Q)//初始化访问队列
{
Q.length=0;
}
voidEnQueue(Queue&Q,inti)//向队列Q中插入元素i
{
++Q.length;
Q.vex[Q.length-1]=i;
}
voidDeQueue(Queue&Q)//队首结点出列
{
for(inti=0;i<=Q.length-2;++i)
Q.vex[i]=Q.vex[i+1];
--Q.length;
}
intlocate(GraphG,NODEvex)//确定结点vex的在矩阵中的位置
{
for(inti=0;iif(vex.vex_value==G.vexs[i].vex_value)
returni;
return-1;
}
intlocateByVexvalue(GraphG,intval)
{
for(inti=0;i{
if(val==G.vexs[i].vex_value)
returni;
}
return-1;
}
voidshortestPath(Graph&G,NODEsource,NODEdest)//寻找最短路径
{
inti,j;
intu;
intw=0;
QueueQ;
InitQueue(Q);
i=locate(G,source);
j=locate(G,dest);
EnQueue(Q,i);
while(Q.length!
=0)
{
u=Q.vex[0];//取出u对其表示的结点进行BFS
DeQueue(Q);
for(w=0;w{
if(G.graph[u][w]!
=0)//判断位置w处的结点是否和u位置的结点邻接
{
if(G.vexs[w].color==white)//如果颜色为白色
{
G.vexs[w].color=grey;//颜色访问后成为灰色
G.vexs[w].depth=G.vexs[u].depth+1;
G.vexs[w].pre=&G.vexs[u];
EnQueue(Q,w);
}
if(w==j)break;//死端则使结点颜色为黑色
}
}
G.vexs[u].color=black;
}
(二)DFS遍历图连通及环
(1)givenagraphG,testifGisconnected.
使用1题中的数据,图如1.1,可以看出此图是连通的。
下面测试程序:
将上述数据中的78改为79,来得到一个不连通的图,来测试不连通的情况。
如下:
测试成功。
源代码:
#include
#include
#defineMAX_VEXVALUE_NUM50
enumCOLOR{white=1,grey,black};
typedefstructNODE
{
intdepth;//结点被访问的深度
intvex_value;//结点表示的值
COLORcolor;
structNODE*pre;
}NODE;
typedefstruct
{
NODEvexs[MAX_VEXVALUE_NUM];//结点
intvexnum;//图中结点数
intgraph[MAX_VEXVALUE_NUM][MAX_VEXVALUE_NUM];//邻接矩阵
}Graph;
voidreadGraph(Graph&gra);
voidprintGraph(Graph&gra);
intlocate(GraphG,NODEvex);//确定结点vex的在矩阵中的位置
intlocateByVexvalue(GraphG,intval);//根据结点中的数确定在邻接矩阵呢中的位置
voiddfs_visited(Graph&G,NODE&p);
voidtestConnected(GraphG);
intmain(intargv,char*argc[])
{
Graphg;
readGraph(g);
printGraph(g);
testConnected(g);
return0;
}
voidreadGraph(Graph&gra)//读取文件,构造一个图
{
intv1,v2;
inti,j;
FILE*fp;
if(!
(fp=fopen("c:
\\graph.txt","r")))
{
perror("不能打开文件!
");
exit(-1);
}
gra.vexnum=0;
while(!
feof(fp))//反复读取文件知道文件结束
{
fscanf(fp,"%d%d",&v1,&v2);
for(i=0;i{
if(v1==gra.vexs[i].vex_value)
break;
}
if(i==gra.vexnum)
{
gra.vexs[gra.vexnum].vex_value=v1;
++gra.vexnum;
}
for(i=0;i{
if(v2==gra.vexs[i].vex_value)
break;
}
if(i==gra.vexnum)
{
gra.vexs[gra.vexnum].vex_value=v2;
++gra.vexnum;
}
}
printf("图中共有%d个节点\n节点为:
",gra.vexnum);
for(i=0;i{
gra.vexs[i].color=white;
gra.vexs[i].depth=0;
gra.vexs[i].pre=NULL;
}
for(i=0;iprintf("%d,%d\n",gra.vexs[i].vex_value,gra.vexs[i].color);
printf("\n");
for(i=0;ifor(j=0;j{
gra.graph[i][j]=0;
}
fseek(fp,SEEK_SET,0);
while(!
(feof(fp)))//第二次读取文件,获取输入边的信息
{
fscanf(fp,"%d%d",&v1,&v2);
i=locateByVexvalue(gra,v1);j=locateByVexvalue(gra,v2);
gra.graph[j][i]=gra.graph[i][j]=1;
}
fclose(fp);
}
voidprintGraph(Graph&gra)//以邻接表形式打印图中各个结点
{
inti;
for(i=0;i{
for(intj=0;jprintf("%d",gra.graph[i][j]);
printf("\n");
}
for(i=0;i{
printf("%d--",gra.vexs[i].vex_value);//由邻接矩阵的索引确定在该行的元素
for(intj=0;j{
if(gra.graph[i][j]!
=0)
printf("%d,",gra.vexs[j].vex_value);
}
printf("\n");
}
}
intlocate(GraphG,NODEvex)//确定结点vex的在矩阵中的位置
{
for(inti=0;iif(vex.vex_value==G.vexs[i].vex_value)
returni;
return-1;
}
intlocateByVexvalue(GraphG,intval)
{
for(inti=0;i{
if(val==G.vexs[i].vex_value)
returni;
}
return-1;
}
voidtestConnected(GraphG)//测试是否连通
{
inti=0;
intbuliantong=-1;
for(i=0;i{
if(G.vexs[i].color==white)
{
++buliantong;//如果不连通则会第二次进入这里,buliantong会大于0
if(buliantong>0)
{
printf("此图不连通!
\n");
return;
}
dfs_visited(G,G.vexs[i]);
}
}
printf("此图连通!
\n");
}
voiddfs_visited(Graph&G,NODE&p)//dfs遍历图
{
p.color=grey;
intw=0;
intu=locate(G,p);
for(w=0;w{
if(G.graph[u][w]!
=0)//判断位置w处的结点是否和u位置的结点邻接
{
if(G.vexs[w].color==white)//如果颜色为白色
{
dfs_visited(G,G.vexs[w]);
}
}
}
p.color=black;
}
(2)givenagraphG,testifGhasacycle,ifso,printacycle
判断是否有环,既判断是否有回边。
对于图1.1.
本程序与只需将2.1题中的函数voiddfs_visited(Graph&G,NODE&p)和voidtestConnected(GraphG)去掉,增加一个circle函数即可。
voidcircle(Graph&G,NODE&p)//判断是否有环并且打印环
{
p.color=grey;
intw=0;
intu=locate(G,p);
for(w=0;w{
if(G.graph[u][w]!
=0)//判断位置w处的结点是否和u位置的结点邻接
{
if(G.vexs[w].color==white)//如果颜色为白色
{
G.vexs[w].pre=&p;
circle(G,G.vexs[w]);
}
else
{
if(G.vexs[w].vex_value!
=p.pre->vex_value)
{
NODE*q=&p;
while(q!
=NULL)
{
printf("%d,",q->vex_value);
q=q->pre;
}
printf("有环\n");
return;
}
}
}
}
p.color=black;
}
(三)N皇后问题
UsingDFStosolvethefollowingproblems:
(1)givenagraphG,testifGisconnected.
使用1题中的数据,图如1.1,可以看出此图是连通的。
下面测试程序:
将上述数据中的78改为79,来得到一个不连通的图,来测试不连通的情况。
如下:
测试成功。
源代码:
#include
#include
#defineMAX_VEXVALUE_NUM50
enumCOLOR{white=1,grey,black};
typedefstructNODE
{
intdepth;//结点被访问的深度
intvex_value;//结点表示的值
COLORcolor;
structNODE*pre;
}NODE;
typedefstruct
{
NODEvexs[MAX_VEXVALUE_NUM];//结点
intvexnum;//图中结点数
intgraph[MAX_VEXVALUE_NUM][MAX_VEXVALUE_NUM];//邻接矩阵
}Graph;
voidreadGraph(Graph&gra);
voidprintGraph(Graph&gra);
intlocate(GraphG,NODEvex);//确定结点vex的在矩阵中的位置
intlocateByVexvalue(GraphG,intval);//根据结点中的数确定在邻接矩阵呢中的位置
voiddfs_visited(Graph&G,NODE&p);
voidtestConnected(GraphG);
intmain(intargv,char*argc[])
{
Graphg;
readGraph(g);
printGra