农夫过河和骑士周游数据结构课程设计报告Word文档下载推荐.docx
《农夫过河和骑士周游数据结构课程设计报告Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《农夫过河和骑士周游数据结构课程设计报告Word文档下载推荐.docx(12页珍藏版)》请在冰豆网上搜索。

(0,0,1,0)
(1,1,1,0)(1,0,1,1)
(0,1,0,0)(0,0,0,1)
(1,1,0,1)
(0,1,0,1)
(1,1,1,1)
安全过河状态图
2.2主要函数模块算法分析
1:
栈的相关函数
PSeqStackInit_SeqStack(void)//栈的初始化
intEmpty_SeqStack(PSeqStacks)//判断栈是否为空栈非空1表示栈空
voidPush_SeqStack(PSeqStacks,intx)//入栈
intPop_SeqStack(PSeqStacks,int*x)//出栈
intSize_SeqStack(PSeqStacks)//顺序栈中元素的个数
voidDestroy_SeqStack(PSeqStack*S)//销毁栈
2,:
求结点直接后继结点个数的函数
intCountAdjoin(MGraph*G,intu)
3:
查找状态(f,w,s,v)在无向图中的位置的函数
intlocated(MGraph*G,intf,intw,ints,intv)
4:
结点值安全状态判断函数
intif_safe(intf,intw,ints,intv)
5:
判断农夫过河的两个状态是否是相邻的函数
intif_connected(MGraph*G,inti,intj)
6:
创建农夫过河状态的无向图
voidCreat_MGraph(MGraph*G)
7:
广优度先遍历遍历所有从状态下标u到状态下标v的路径函数
voidBFS_path(MGraph*G,intu,intv)
8:
输出所有从状态下标为u到状态下标为v的所有简单路径
voidprint_path(MGraph*G,intu,intv)
2.3部分函数源代码
path[u][m]为状态下标u的直接后继状态下标m表示状态下标u的直接后继结点个数:
intpath[MaxVertexNum][MaxVertexNum];
主要结构:
typedefstruct
{
intfarmer;
intwolf;
intsheep;
intvegetable;
}vertexType;
//顶点结点类型
typedefstruct
vertexTypevertex[MaxVertexNum];
intedges[MaxVertexNum][MaxVertexNum];
intvertexNum;
}MGraph;
//邻接矩阵存储结构类型
intdata[MAXSIZE];
inttop;
//栈顶
}SeqStack,*PSeqStack;
voidBFS_path(MGraph*G,intu,intv)//深度优先遍历从状态下标u到状态下标v
inti,j,m,n;
PSeqStackS;
S=Init_SeqStack();
Push_SeqStack(S,v);
visited[u]=TRUE;
//改变路径头结点的访问标志为TRUE
Push_SeqStack(S,u);
while(!
Empty_SeqStack(S))
{
Pop_SeqStack(S,&
u);
m=1;
for(i=0;
i<
G->
vertexNum;
i++)//判定后继结点的个数及将其后继结点访问标志置TRUE
{
if(G->
edges[u][i]&
&
!
visited[i])
{
path[u][m]=i;
//将下标为U的后继结点下标赋给path[u][m]m用来记录直接后继结点的个数
visited[i]=TRUE;
m++;
}
}
for(j=1;
j<
=m;
j++)
n=path[u][j];
if(n!
=v)//判断结束标志如果数的后继结点下标与要找的一条路径最后一个结点的下标不一样则将后继元素下标入栈
Push_SeqStack(S,n);
else//或者将栈中的最后一个元素出栈
Pop_SeqStack(S,&
while(Size_SeqStack(S)>
2)//栈中元素个数大于2则一直出栈
Pop_SeqStack(S,&
m=1;
for(i=0;
i++)
if(G->
visited[i])//path[u][m]为状态下标u的直接后继状态下标m表示状态下标u的后继结点个数
{
path[u][m]=i;
visited[i]=TRUE;
m++;
}
}
Destroy_SeqStack(&
S);
//销毁栈
}
voidprint_path(MGraph*G,intu,intv)//输出所有从状态下标为u到状态下标为v的所有简单路径
intn,k,i,j,m,t,a,l;
k=u;
j=1;
visited[u]=FALSE;
//改变第一个结点的访问标志
path[v][1]=-1;
//将一条路径的最后一个顶点的后继结点下标置为无穷大
while(k!
=-1)
printf("
\t\tNO%d:
(%d,%d,%d,%d)\n"
j++,G->
vertex[k].farmer,G->
vertex[k].wolf,G->
vertex[k].sheep,G->
vertex[k].vegetable);
m=CountAdjoin(G,k);
if(m==0)//结束条件后继结点个数为零
break;
if(m!
=1)
for(i=m;
i>
0;
i--)//输出某个结点后的所有分支后继结点
t=k;
t=path[t][i];
n=0;
l=j;
while(t!
if(n<
=1)//(某个结点分支后继结点个数)//用于转换输出另外一条分支后继结点的判断条件
{
printf("
\tNO%d:
(%d,%d,%d,%d)"
l++,G->
vertex[t].farmer,G->
vertex[t].wolf,G->
vertex[t].sheep,G->
vertex[t].vegetable);
a=t;
t=path[t][1];
visited[t]=FALSE;
n++;
}
else
break;
printf("
\n"
);
j=l;
k=a;
}
k=path[k][1];
实验结果
结果分析:
农夫过河的安全步骤:
NO1:
农夫,狼,羊,白菜都在河的左岸
NO2:
农夫带羊到河的右岸
NO3:
农夫回到河的左岸
NO4:
农夫带狼到河的右岸或者农夫带白菜到河的右岸
NO5:
农夫带羊回到河的左岸或者农夫带羊回到河的左岸
NO6:
农夫带狼到河的右岸
NO7:
NO8:
农夫带羊到和的右岸
实验心得
通过农夫过河的实验,使我初步了解解决一些复杂较难问题的思路和掌握了解决问题的方法。
通过该实验的代码编程过程中也进一步提高了我对c语言的掌握,掌握了栈,深度广度遍历的算法,也提高了我对算法的学习设计能力,同时提高了编程调试的能力,使我遇到那些逻辑上的错误,能通过自己一点一点的调试,搜寻逻辑错误所在处。
在编程调试中遇相关的问题时,让我明白遇到问题不可怕,怕的是遇到问题不想解决或者没有解决问题恒定的决心,即使一些问题在困难,当时对遇到的可能丝毫没有头绪,只要一点点的对问题剖析,哪怕在困难的问题也会被解决。
实验二
实验要求:
1.1:
实验目的
提高分析设计解决问题的能力,并掌握选择策略的图的深度优先搜索等先关的知识。
1.2:
实验内容问题描述
马随机放在国际象棋8*8的方格中,马按照走马的规则进行移动,要求马走过每个格走过仅走过一次并且每个格都走过,编程求输出马走过的路径
1.3:
实验输出
输出骑士周游的路径
2.1:
在国际象棋的棋盘上,马共有八个可能的跳跃方向。
设置一组坐标增量来描述这八个条约方向:
①
(1,2)
②
(2,1)
③
(2,-1)
④
(1,-2)
⑤
(-1,-2)
⑥
(-2,-1)
⑦
(-2,1)
⑧
(-1,2)
2.2:
主要算法模块分析
voidgo(intn,intx,inty)递归算法模块
2.3:
主要源代码
#include<
stdio.h>
#defineN8
intditu[N][N]=//棋盘初始化所有点为零
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0}
};
intpath[N][N];
//记录周游路径
intflag=0;
//结束标记
intincX[]={1,2,2,1,-1,-2,-2,-1};
//指示方向横坐标
intincY[]={-2,-1,1,2,2,1,-1,-2};
//指示方向纵坐标
voidgo(intn,intx,inty)
if(n>
=(N*N))//判断是否走完整个地图
flag=1;
path[x][y]=n;
if(flag==1)//递归结束标志
return;
path[x][y]=n;
//将骑士走的路径记录
ditu[x][y]=1;
//标记坐标(x,y)点走过
for(inti=0;
8;
i++)//8方向探路
if((((x+incX[i])>
=0)&
((x+incX[i])<
N))&
(((y+incY[i])>
((y+incY[i])<
(ditu[x+incX[i]][y+incY[i]]==0))
go(n+1,x+incX[i],y+incY[i]);
//递归周游
ditu[x][y]=0;
//8个方向中如果探测方向不是合适的落马点则清除马走过的标记
return;
voidmain()
printf("
骑士从棋盘左上角开始的周游路径\n"
go(1,0,0);
//设置从0,0开始出发
for(inti=0;
N;
i++)//输出路径
for(intj=0;
j++)
printf("
%4d"
path[i][j]);
通过该实验让我掌握了数据结构进一步了解,对图的深度优先遍历算法的由来更深的理解与体会,对骑士周游问题有自己的见解和体会。
让我学习的理论与实际运用相结合,提高了独立解决问题的能力。