数据结构马的遍历.doc
- 文档编号:238760
- 上传时间:2022-10-07
- 格式:DOC
- 页数:6
- 大小:46KB
数据结构马的遍历.doc
《数据结构马的遍历.doc》由会员分享,可在线阅读,更多相关《数据结构马的遍历.doc(6页珍藏版)》请在冰豆网上搜索。
马的遍历
·问题描述
设计要求是马从棋盘上的一个位置出发,然后按照中国象棋的规则—马走日,来走下一步,直到马走完棋盘上的每一个位置终止。
·设计思路
首先将棋盘每个位置的标记为0,然后对棋盘周围的两个格子标记为1,用于检测,相当于棋盘的边界。
每个节点的包含马走过的位置以及方向。
将节点以及下一次要走的方向压入栈中,然后对每个节点可以走的方向进行判断,然后找出最佳的方向。
·数据结构设计
将节点走过的位置以及方向封装到一起,利用栈的特点实现马的遍历。
·功能函数设计
voidInit_Path(path*p)初始化栈
intPush_Path(path*p,pathnodet,intv)将节点以及下一次走的方向压入栈中
intEmpty(pathp)判断栈是否为空
intPop_Path(path*p,pathnode*t)出栈
intCount(intx,inty)计算节点周围可以移动的所有方向
intFind_Direction(intx,inty)寻找下一次移动的方向
voidRound(intx,inty,intv)马的遍历函数
voidMark_Dir(intv)标志方向函数
voidMark_Che(intv)标志棋盘函数
·程序代码
#include
#include
intchessboard[14][13];//二维数组表示棋盘每个棋子位置,其中棋盘四周有两个格子,用于检测
intCanPass[14][13][8];//每个棋子的八个方向哪些可以走
typedefstruct{//棋盘的八个方向
inty,x;
}direction;
directiondir[8]={{2,1},{1,2},{-1,2},{-2,1},{-2,-1},{-1,-2},{1,-2},{2,-1}};//八个方向
//栈的设计
typedefstruct{
intx,y;//走过位置
intdi;//方向
}pathnode;
typedefstruct{
pathnodepa[90];
inttop;
}path;//顺序栈
voidInit_Path(path*p)
{//初始化栈
p->top=-1;
}
intPush_Path(path*p,pathnodet,intv)
{//压节点及其向下一位移动的方向入栈
if(p->top>=63+26*v)
return-1;
else
{
p->top++;
p->pa[p->top].x=t.x;
p->pa[p->top].y=t.y;
p->pa[p->top].di=t.di;
return1;
}
}
intEmpty(pathp)
{//判断栈是否为空
if(p.top<0)return1;
return0;
}
intPop_Path(path*p,pathnode*t)
{//出栈
if(Empty(*p))
return-1;
else
{
t->x=p->pa[p->top].x;
t->y=p->pa[p->top].y;
t->di=p->pa[p->top--].di;
return1;
}
}
intCount(intx,inty)
{//计算每个节点周围有几个方向可以走
intcount=0,i=0;
for(i=0;i<8;i++)
if(chessboard[x+1+dir[i].x][y+1+dir[i].y]==0)
count++;
returncount;
}
intFind_Direction(intx,inty)
{//寻找下一个方向
intdire,min=9,count,d=9;
for(dire=0;dire<8;dire++)
{
if(chessboard[x+1+dir[dire].x][y+1+dir[dire].y]==0&&
CanPass[x+1][y+1][dire]==0)
{
count=Count(x+dir[dire].x,y+dir[dire].y);
if(min>count)
{
min=count;
d=dire;
}
}
}
if(d<9)
returnd;
else
return-1;
}
voidRound(intx,inty,intv)//x,y表示出发位置
{//马的遍历函数
intnum=1,t,i;
pathp;
pathnodef;
Init_Path(&p);
for(num=1;num<=64+26*v;num++)
{
t=Find_Direction(x,y);
if(t!
=-1)
{//正常找到下一个方向的情况下
chessboard[x+1][y+1]=num;
f.x=x;f.y=y;f.di=t;
Push_Path(&p,f,v);
x=x+dir[t].x;y=y+dir[t].y;
}
elseif(num==64+26*v&&chessboard[x+1][y+1]==0)
{//最后一次时t肯定是-1
chessboard[x+1][y+1]=num;
f.x=x;f.y=y;f.di=t;
Push_Path(&p,f,v);
}
else
{
if(Pop_Path(&p,&f)==-1)
{//出栈且栈为空的情况
printf("!
!
!
!
!
!
!
!
!
!
!
!
无法为您找到一条适合的路径!
!
!
!
!
!
!
!
!
!
!
!
\n");
exit(0);
}
num-=2;
x=f.x;y=f.y;
CanPass[x+1][y+1][f.di]=1;
}//endelse
}
//根据栈中信息打印出骑士行走路径
printf("马的遍历结果如下:
\n");
printf("\b\b\n");
for(i=0;i<8+2*v;i++)
{//根据棋盘数组来打印
for(t=0;t<8+v;t++)
printf("%4d",chessboard[i+2][t+2]);
printf("\n");
}
}
voidMark_Dir(intv)
{//由于三维数组赋初值比较困难,因而采用单独的函数实现
inti,j,k;
for(i=0;i<12+2*v;i++)
for(j=0;j<12+v;j++)
for(k=0;k<8;k++)
CanPass[i][j][k]=0;
}
voidMark_Che(intv)
{//标志棋盘函数
inti,j;
for(i=0;i<12+2*v;i++)//首先全部标记为0
for(j=0;j<12+v;j++)
chessboard[i][j]=0;
for(i=0;i<2;i++)//前面两行标记为1
for(j=0;j<12+v;j++)
chessboard[i][j]=1;
for(j=0;j<2;j++)//前面两列标记为1
for(i=0;i<12+2*v;i++)
chessboard[i][j]=1;
for(j=10+v;j<12+v;j++)//后面两列标记为1
for(i=0;i<12+2*v;i++)
chessboard[i][j]=1;
for(i=10+2*v;i<12+2*v;i++)
for(j=0;j<12+v;j++)//后面两行标记为1
chessboard[i][j]=1;
}
voidmain()
{//主函数
intx,y,v=1;
charch='y';
while(ch=='y')
{
Mark_Che(v);
Mark_Dir(v);
while
(1)
{
printf("请输入入口点横坐标:
");
scanf("%d",&x);
if(x<1||x>8+2*v)
printf("输入错误,请重新输入!
(横坐标在1-%d之间)\n",8+2*v);
else
break;
}
while
(1)
{
printf("请输入入口点纵坐标:
");
scanf("%d",&y);
if(y<1||y>8+v)
printf("输入错误,请重新输入!
(纵坐标在1-%d之间)\n",8+v);
else
break;
}
Round(x,y,v);
printf("继续(是:
y;否:
其他):
");
fflush(stdin);
scanf("%c",&ch);
}
}
·运行与测试
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 遍历