数据结构 马踏棋盘
数据结构 马踏棋盘 设计报告
《数据结构》课程设计报告课程名称:《数据结构》课程设计课程设计题目:姓名:院系:专业:年级:学号:指导教师:2011年月日目录1、程序设计的目的2、设计题目3、分析4、设计思想5、算法6、测试结果7、调试分析8、小结1、课程设计的目的1、熟练使用C++语言编写程序,解决实际问题;2、了解并掌握数据结构与算法的设计方法,具备初步的独立分析和设计能力;3、初步掌握软件开发过程的问题分析、系统设计、程序编码、测试等基本方法和技能;4、提高综合运用所学的理论知识和方法独立分析和解决问题的能力;5、学习并熟悉栈的有关操作;6、利用栈实现实际问题;2、设计题目【马踏棋盘】*问题描述:将马随机放在国际象棋的8X8棋盘Bo阿rd[0..7,0..7]的某个方格中,马按走棋规则进行移动。
要求每个方格上只进入一次,走遍棋盘上全部64个方格。
编制非递归程序,求出马的行走路线,并按求出的行走路线,将数字1,2,…,64依次填入8X8的方阵输出之。
*测试数据:由读者指定,可自行指定一个马的初始位置。
*实现提示:每次在多个可走位置中选择一个进行试探,其余未曾试探过的可走位置必须用适当结构妥善管理,以备试探失败时的“回溯”(悔棋)使用。
并探讨每次选择位置的“最佳策略”,以减少回溯的次数。
3、分析确定输入值的范围,输入马的初始行坐标X和Y,X和Y的范围都是1到8之间。
程序的功能是输出马走的步骤,要使马从任一起点出发,通过程序能找到下一个地点,然后遍历整个棋盘。
每次在多个可走位置中选择一个进行试探,其余未曾试探过的可走位置必须用适当结构妥善管理,以备试探失败时的“回溯”(悔棋)使用。
并探讨每次选择位置的“最佳策略”,以减少回溯的次数。
输出时可以用二维数组。
4、设计思想输入马初始位置的坐标。
将初始位置进栈,经过一个while循环,取出符合条件的栈顶元素。
利用函数,找出栈顶元素周围未被占用的新位置,如果有,新位置入栈;否则弹出栈顶元素。
C++ 数据结构课程设计 马踏棋局文档
课程设计题目1 问题描述将马随机放在国际象棋的8*8棋盘Board[8][8]的某个方格中,马按走棋规则进行移动,要求每个方格上只进入一次,走遍棋盘上全部64个方格2 基本要求(1)采用图形界面实现该游戏。
(2)从键盘输入马的初始位置。
(3)编制程序,求出马的行走路线,并按求出的行走路线,将数字1,2,…,64依次填入一个8* 8的方阵,并输出之。
3系统分析与设计3.1 数据结构逻辑结构为线性结构,用顺序栈。
坐标点用已结构体来表示,并将其的位置放在s[step]的栈中,而且将每走一步的坐标放在另一栈s1中3.2 算法设计1.程序框架及功能模块划分:2.设计功能的分析与实现void exit(point p)参数:point功能:计算出下一步可能位置,按其各个位置下一个位置的和压栈到s[]中算法描述:接受参数传来的值,按次序加上int horizontal[]={2,1,-1,-2,-2,-1,1,2};int vertical[]={-1,-2,-2,-1,1,2,2,1};再根据legal函数来判断是否合法(x(0~7),y(0~7))是,则保存在point ap[]中,再按各自下一步的数目从大到小排序。
最后,将ap[]中的点压栈。
int number(point p)参数:point功能:找出当前位置下一步的各种可能位置,计算可能之和算法描述:接受参数传来的值,按次序加上int horizontal[]={2,1,-1,-2,-2,-1,1,2};int vertical[]={-1,-2,-2,-1,1,2,2,1};再根据legal函数来判断是否合法(x(0~7),y(0~7))是,则加1并将值返回void next(point p)参数:point功能:/找出各个位置并将其步数记录算法描述:将其步数记录在board[][]的相应位置,并将这点压栈到s1,判断步数是否小于64,再根据这四个条件选择执行其中的一个,再递归调用next.bool legal(point p)参数:point功能:判断是否可行,合法(是否在棋盘上,是否走过)算法描述:用这样的语句if((p.x>=0)&&(p.x<n)&&(p.y<n)&&(p.y>=0)&&(bo ard[p.x][p.y]==0))return true;elsereturn false;4 测试数据及结果测试数据和运行输出及结果分析输入x(0-7),y(0-7)0 01 34 3 18 49 32 13 164 19 56 33 14 17 50 3157 2 35 48 55 52 15 1220 5 60 53 36 47 30 5141 58 37 46 61 54 11 266 21 42 59 38 27 64 2943 40 23 8 45 62 25 1022 7 44 39 24 9 28 63 Press any key to continue输入x(0-7),y(0-7)0 9输入不合法,重输入!输入x(0-7!),y(0-7!)4 530 27 10 49 40 25 8 511 48 29 26 9 6 39 2428 31 56 45 50 41 4 747 12 51 42 19 44 23 3832 57 46 55 52 1 18 313 64 53 60 43 20 37 2258 33 62 15 54 35 2 1763 14 59 34 61 16 21 36 Press any key to continue5 总结调试过程中遇到的主要问题,是如何解决的;问题1:只走到63步原因:第64步就走完了,并且s[62]中只有一个元素,这个判断条件(s[step].base==s[step].top&&number(p2)==0)满足就进入了,而始终不能走完解决方法:改了判断条件,改为((s[step].base==s[step].top&&number(p2)==0)&&step!=n* n-1)解决方案:用InitStack(s1)初始化问题3:冒泡排序超出边界原因:循环次数大解决方案:减少循环次数看了其他同学,都差不多,我已经按马的下一位置最难的先走,再走难度次之的位置。
数据结构实验报告马踏棋盘
目录1 课程设计的目的 (x)2 需求分析 (x)3 课程设计报告内容 (x)1、概要设计 (x)2、详细设计 (x)3、调试分析 (x)4、用户手册 (x)5、测试结果 (x)6、程序清单 (x)4 小结 (x)5 参考文献 (x)2011年5月23日1、课程设计的目的(1)熟练使用栈和队列解决实际问题;(2)了解并掌握数据结构与算法的设计方法,具备初步的独立分析和设计能力;(3)初步掌握软件开发过程的问题分析、系统设计、程序编码、测试等基本方法和技能;(4)提高综合运用所学的理论知识和方法独立分析和解决问题的能力;2、需求分析*问题描述:将马随机放在国际象棋的8X8棋盘Bo阿rd[0..7,0..7]的某个方格中,马按走棋规则进行移动。
要求每个方格上只进入一次,走遍棋盘上全部64个方格。
编制非递归程序,求出马的行走路线,并按求出的行走路线,将数字1,2,…,64依次填入8X8的方阵输出之。
*测试数据:由读者指定,可自行指定一个马的初始位置。
*实现提示:每次在多个可走位置中选择一个进行试探,其余未曾试探过的可走位置必须用适当结构妥善管理,以备试探失败时的“回溯”(悔棋)使用。
并探讨每次选择位置的“最佳策略”,以减少回溯的次数。
3、课程设计报告内容根据分析先建了2个结构体struct PosType //马的坐标位置类型{int m_row; //行值int m_col; //列值};struct DataType //栈的元素类型{PosType seat; //马在棋盘中的“坐标位置”int di; //换方向的次数};chess::chess()bool chess::chessPath(PosType start) //在棋盘中进行试探寻找下一步位置并同时记录位置,以及涉及到的入栈出栈void chess::Print() //打印马走的路径PosType chess::NextPos(PosType a,int di)//根据当前点的位置a和移动方向di,试探下一位置4、总结一、这次课程设计的心得体会通过实践我的收获如下:1、巩固和加深了对数据结构的理解,提高综合运用本课程所学知识的能力。
数据结构 马踏棋盘
理解栈的特性“后进先出” 和队列的特性“先进先出”。
仅仅认识到栈和队列是两种特殊的线性表是远远不够的,本次实验的目的在于更深入的了解栈和队列的特性,以便在实际问题 背景下灵便运用他们。
在了解他特性的基础上,还将巩固对这种结构的构造方法的理解。
要求:在国际象棋 8×8 棋盘上面,按照国际象棋规则中马的行进规则,实现从任意初始 位置,每一个方格只进入一次,走遍棋盘上全部 64 个方格。
编制程序,求出马的行走路线,并 按求出的行走路线, 将数字 1,2,…,64 挨次填入一个8×8 的方阵, 并输出它的行走路线 (棋 盘如图所示)。
输入:任意一个起始位置;输出:无重复踏遍棋盘的结果,以数字 1-64 表示行走路线。
为了实现上述程序功能,可以采用顺序栈或者链栈来存储它的数据,本实验所需要的存储空间不是很大,不需动态的开辟不少空间,所以采用相对简单的顺序栈来存储数据,既方 便有简单,而用链栈在实现上相对照顺序栈复杂的一点。
1234567414285 523176 3H6 7ADT Stack{数据对象:D={ai| ai∈(0,1,…, 9),i=0,1,2,…, n,n≥0}数据关系: R={< ai-1, ai >| ai-1, ai∈D,i=1,2,…, n}} ADT Stack1、主程序模块:void main(){定义变量;接受命令;处理命令;退出;}2、起始坐标函数模块——马儿在棋盘上的起始位置;3、探寻路径函数模块——马儿每一个方向进行尝试,直到试完整个棋盘;4、输出路径函数模块——输出马儿行走的路径;主程序模块输入的初始位置是否正确否是起始坐标函数模探寻路径函数模输出路径函数模结束#include<stdio.h>#define MAXSIZE 100#define N 8int board[8][8]; //定义棋盘int Htry1[8]={1,-1,-2,2,2,1,-1,-2};/*存储马各个出口位置相对当前位置行下标的增量数组*/ int Htry2[8]={2,-2,1,1,-1,-2,2,-1};/*存储马各个出口位置相对当前位置列下标的增量数组*/struct Stack{int i;int j;int director; }stack[MAXSIZE]; int top=-1; //定义栈类型//行坐标//列坐标//存储方向//定义一个栈数组//栈指针void InitLocation(int xi,int yi); //马儿在棋盘上的起始位置坐标int TryPath(int i,int j); void Display(); //马儿每一个方向进行尝试,直到试完整个棋盘//输出马儿行走的路径void InitLocation(int xi,int yi){int x,y; //定义棋盘的横纵坐标变量top++; //栈指针指向第一个栈首stack[top].i=xi; //将起始位置的横坐标进栈stack[top].j=yi; //将起始位置的纵坐标进栈stack[top].director=-1; //将起始位置的尝试方向赋初值board[xi][yi]=top+1; //标记棋盘x=stack[top].i; //将起始位置的横坐标赋给棋盘的横坐标y=stack[top].j; //将起始位置的纵坐标赋给棋盘的纵坐标if(TryPath(x,y)) //调用马儿探寻函数,如果马儿探寻整个棋盘返回 1 否则返回 0 Display(); //输出马儿的行走路径elseprintf("无解");}int TryPath(int i,int j) {int find,director,number,min; int i1,j1,h,k,s;int a[8],b1[8],b2[8],d[8]; while(top>-1){//定义几个暂时变量//定义几个暂时变量//定义几个暂时数组//栈不空时循环for(h=0;h<8;h++){//用数组 a[8]记录当前位置的下一个位置的可行路径的条数number=0;i=stack[top].i+Htry1[h];j=stack[top].j+Htry2[h];b1[h]=i;b2[h]=j;if(board[i][j]==0&&i>=0&&i<8&&j>=0&&j<8){for(k=0;k<8;k++)//如果找到下一位置{i1=b1[h]+Htry1[k];j1=b2[h]+Htry2[k];if(board[i1][j1]==0&&i1>=0&&i1<8&&j1>=0&&j1<8)//如果找到下一位置number++;}a[h]=number;}} //记录条数//将条数存入数组 a[8]中for(h=0;h<8;h++){//根据可行路径条数小到大按下表排序放入数组 d[8]中min=9;for(k=0;k<8;k++)if(min>a[k]){min=a[k];d[h]=k; //将下表存入数组 d[8]中s=k;}a[s]=9;}director=stack[top].director;if(top>=63)return (1); find=0; //如果走完整个棋盘返回 1 //表示没有找到下一个位置for(h=director+1;h<8;h++) //向八个方向进行探寻{i=stack[top].i+Htry1[d[h]];j=stack[top].j+Htry2[d[h]];if(board[i][j]==0&&i>=0&&i<8&&j>=0&&j<8) //如果找到下一位置{find=1;break;}}if(find==1){//表示找到下一个位置//如果找到下一个位置进栈stack[top].director=director; //存储栈结点的方向top++;stack[top].i=i;stack[top].j=j;stack[top].director=-1;board[i][j]=top+1;}else{//栈指针前移进栈//重新初始化下一栈结点的尝试方向//标记棋盘//否则退栈board[stack[top].i][stack[top].j]=0; //清除棋盘的标记top-- ; //栈指针前移退栈}}return (0);}void Display(){int i,j;for(i=0;i<N;i++){for(j=0;j<N;j++)printf("\t%d ",board[i][j]); //输出马儿在棋盘上走过的路径printf("\n\n");}printf("\n");}void main(){int i,j;int x,y;for(i=0;i<N;i++)for(j=0;j<N;j++)board[i][j]=0;for(;;)//初始化棋盘{printf("Please input importpoint(1<=x<=8 and 1<=y<=8)\n");printf("Input x = ");scanf("%d",&x); printf("Input y = "); scanf("%d",&y); //输入起始位置的横坐标//输入起始位置的纵坐标if(x>=1&&x<=8&&y>=1&&y<=8)break;printf("Your input is worng\n");}printf("begin with %d board:\n\n", 8*(x-1)+y);InitLocation(x-1,y-1); //调用起始坐标函数}(1)本次实验的主要目的是在于掌握和理解栈的特性和它的应用。
利用顺序栈或循环队列的存储来实现马踏棋盘的算法
河南工业大学实验报告课程数据结构实验名称利用顺序栈或循环队列的存储来实现马踏棋盘的算法学院信息科学与工程学院专业班级姓名学号实验报告日期 2009 年 4 月 1 日教师审批签字实验报告一实验题目:马踏棋盘二实验要求:将马放在国际象棋的8*8棋盘Board[8][8]的某个方格中,马按走棋的规则进行移动。
要求每个方格只能进入一次。
走遍棋盘上的全部的64个方格。
输入:任意一个起始位置.输出:无重复踏遍棋盘的结果,以数字1-64表示行走路线.数据结构要求:采用顺序栈或者链栈实现三实验目的:1熟悉栈的定义和栈的基本操作2 熟悉每一种栈操作的一般函数实现和成员函数实现。
3在实际问题背景下灵活运用它们,并巩固这两种结构的构造方法四程序设计如下:#include "stdio.h"#define M 70#define FALSE 0#define TRUE 1typedef struct node //结点的类型{int vec,x,y;struct node *link;}listnode;#define MAXSIZE 70typedef struct{int stack[MAXSIZE];int top;}seqstack;seqstack *s; //顺序栈指针listnode ag[M];int flag[M];void setnull(seqstack *s){s->top=-1;}int push(seqstack *s,int x){if(s->top>=MAXSIZE-1){printf("stack overflow!\n");return FALSE;}else{s->stack[++s->top]=x;/*栈顶指针上移,数据元素入栈*/ return TRUE;}}int pop(seqstack *s)/*出当前栈S的栈顶元素*/{ int p;if(s->top<0){printf("stack empty!\n");/*栈空,返回空值 */ return NULL;}else{s->top--;return(s->stack[s->top+1]);}/*由于return语句的特点,必须先使top减1,然后再执行return语句。
数据结构课程设计 马踏棋盘分解
杭州师范大学钱江学院课程设计2013 年12 月21 日目录一.概述 (3)二.总体方案设计 (3)三.详细设计 (4)四.最终输出 (6)五.课程设计总结 (10)参考文献 (13)一概述1.课程设计的目的(1)课题描述设计一个国际象棋的马踏遍棋盘的演示程序。
(2)课题意义通过“马踏棋盘”算法的研究,强化了个人对“栈”数据结构的定义和运用,同时也锻炼了自身的C语言编程能力。
另一方面,通过对“马踏棋盘” 算法的研究,个人对“迷宫”、“棋盘遍历”一类的问题,有了深刻的认识,为今后解决以此问题为基础的相关的问题,打下了坚实的基础。
(3)解决问题的关键点说明解决问题的关键首先要熟练掌握 C语言编程技术,同时能够熟练运用“栈”数据结构。
另外,态度也是非常重要的。
在课程设计过程中,难免会遇到困难,但是不能轻易放弃,要肯花时间,能静得下心,积极查阅相关资料,积极与指导老师沟通。
2.课程设计的要求(1)课题设计要求将马随机放在国际象棋的8X 8棋盘Board[0〜7][0〜7]的某个方格中,马按走棋规则进行移动。
要求每个方格只进入一次,走遍棋盘上全部64个方格。
编制非递归程序,求出马的行走路线,并按求出的行走路线,将数字1,2,…,64依次填入一个8X 8的方阵,输出之。
程序由回溯法和贪心法实现,比较两种算法的时间复杂度。
(2)课题设计的思路首先,搞清楚马每次在棋盘上有 8个方向可走,定义两个一位数组,来存储马下一着点的水平和纵向偏移量。
程序再定义一个8*8二维数组,初始所有元素置0,起始点元素置1。
若为回溯法,初始方向数据(一维数组下标) 入栈。
随后,马从起始点开始,每次首先寻找下一可行的着点,然后记下方向,方向数据入栈,把该位置元素置为合适的序列号,若无下一可行着点,则回溯,寻找下一方向位置着点,以此类推,直到 64填入数组中,则输出二维数组,即为马可走的方案。
若为贪婪法,选择下一出口的贪婪标准是在那些允许走的位置中,选择出口最少的那个位置。
马踏棋盘算法
马踏棋盘算法介绍1.马踏棋盘算法,也称骑⼠周游问题2.规则:将马随机放在国际象棋的 8×8 棋盘[0~7][0~7]的某个⽅格中,马按⾛棋规则(马⾛⽇字)进⾏移动,要求每个⽅格只进⼊⼀次,⾛遍棋盘上全部 64 个⽅格3.基本思想:图的深度优先搜索 + 贪⼼算法(优化)步骤1.创建⼀个⼆维数组代表棋盘2.将当前位置设置为已经访问,把当前马在棋盘的位置标记为第⼏步(step),然后根据当前位置,计算马还能⾛哪些位置,并放⼊ArrayList,最多有8个位置3.获取到ArrayList后,⽤贪⼼算法优化4.遍历ArrayList中存放的所有位置,判断哪个位置可以⾛通,如果⾛通,就继续,⾛不通,就回溯5.判断是否⾛完整个棋盘,使⽤step和应该⾛的步数⽐较,如果没有达到数量,则表⽰没有完成任务,并将整个棋盘置0贪⼼算法优化ArrayList1.基本思想:根据当前这个⼀步的所有的下⼀步的选择位置,进⾏⾮递减(即不严格递增)排序,减少回溯的次数步骤(1)传⼊Comparotor,重写ArrayList的sort⽅法(2)获取ArrayList所有位置的通路个数,按⾮递减排序(3)即当前位置的下⼀步的下⼀步通路最少,就优先选择代码实现import java.awt.*;import java.util.ArrayList;import java.util.Arrays;import parator;public class KnightTravel {//骑⼠周游问题public int row;//棋盘的⾏数public int column;//棋盘的列数public int[][] chessboard;//棋盘public boolean[][] visited;//标记棋盘的各个位置是否被访问过,true:已访问public boolean finished;//标记是否棋盘的所有位置都被访问,若为true,表⽰算法计算成功public int step = 1;//初始为第⼀步public static void main(String[] args) {KnightTravel knight = new KnightTravel(8, 8);long start = System.currentTimeMillis();knight.travel(knight.chessboard, 0, 0, knight.step);long end = System.currentTimeMillis();System.out.println("共耗时: " + (end - start) + " 毫秒");knight.result();}public KnightTravel(int row, int column) {this.row = row;this.column = column;this.chessboard = new int[row][column];this.visited = new boolean[row][column];}public void result() {//打印算法结果for (int[] row : chessboard) {System.out.println(Arrays.toString(row));}}//马踏棋盘算法//chessboard:棋盘,row:马⼉当前的位置的⾏,从0开始,column:马⼉当前的位置的列,从0开始,step:第⼏步,初始位置是第1步 public void travel(int[][] chessboard, int row, int column, int step) {chessboard[row][column] = step;visited[row][column] = true; //标记该位置已经访问//获取当前位置可以⾛的下⼀个位置的集合ArrayList<Point> access = next(new Point(column, row));sort(access);//对access进⾏⾮递减排序while (!access.isEmpty()) {Point next = access.remove(0);//取出下⼀个可以⾛的位置if (!visited[next.y][next.x]) {//判断该点是否已经访问过travel(chessboard, next.y, next.x, step + 1);}}if (step < this.row * this.column && !finished) {//⽆路可⾛且未⾛完,就回溯到上⼀位置chessboard[row][column] = 0;visited[row][column] = false;} else {//成功⾛完时,finished是防⽌回溯时将最优解覆盖掉finished = true;}}//根据当前位置(curPoint),计算马还能⾛哪些位置(point),并放⼊⼀个集合中(ArrayList), 最多有8个位置public ArrayList<Point> next(Point curPoint) {//储存马在当前位置的通路ArrayList<Point> access = new ArrayList<>();//Point对象中,属性x代表列,属性y代表⾏Point point = new Point();//以下操作,判断马的8个⽅向是否可⾏,并记录通路位置,但不记录该位置是否已访问if ((point.x = curPoint.x - 2) >= 0 && (point.y = curPoint.y - 1) >= 0) {access.add(new Point(point));}if ((point.x = curPoint.x - 1) >= 0 && (point.y = curPoint.y - 2) >= 0) {access.add(new Point(point));}if ((point.x = curPoint.x + 1) < column && (point.y = curPoint.y - 2) >= 0) {access.add(new Point(point));}if ((point.x = curPoint.x + 2) < column && (point.y = curPoint.y - 1) >= 0) {access.add(new Point(point));}if ((point.x = curPoint.x + 2) < column && (point.y = curPoint.y + 1) < row) {access.add(new Point(point));}if ((point.x = curPoint.x + 1) < column && (point.y = curPoint.y + 2) < row) {access.add(new Point(point));}if ((point.x = curPoint.x - 1) >= 0 && (point.y = curPoint.y + 2) < row) {access.add(new Point(point));}if ((point.x = curPoint.x - 2) >= 0 && (point.y = curPoint.y + 1) < row) {access.add(new Point(point));}return access;}//根据当前这个⼀步的所有的下⼀步的选择位置,进⾏⾮递减(不严格递增)排序, 减少回溯的次数public void sort(ArrayList<Point> access) {access.sort(new Comparator<Point>() {@Overridepublic int compare(Point o1, Point o2) {int count1 = next(o1).size();int count2 = next(o2).size();if (count1 < count2) {return -1;} else if (count1 == count2) {return 0;} else {return 1;}}});}}。
数据结构马踏棋盘
数据结构马踏棋盘第一点:马踏棋盘的起源与发展马踏棋盘,是一种源自中国传统的棋类游戏,具有悠久的历史和丰富的文化内涵。
它是在象棋的基础上演变而来的一种棋类运动,以马作为主要棋子,通过马的移动来占领对方的棋盘。
马踏棋盘不仅具有高度的策略性和技巧性,而且蕴含着深厚的哲学思想和人生哲理。
从历史角度看,马踏棋盘的起源可以追溯到中国古代的战国时期。
当时,诸侯割据,战争频繁,人们为了娱乐和消磨时间,便创造了这种棋类游戏。
随着时间的推移,马踏棋盘逐渐在全国各地流传开来,并逐渐形成了不同的地域流派和玩法。
从文化角度看,马踏棋盘不仅是一种游戏,更是一种艺术。
它的棋盘布局、棋子造型、规则设计等方面都蕴含着丰富的中国传统文化元素。
例如,棋盘的布局模仿了中国古代的宫殿建筑,棋子的造型则借鉴了古代兵器和宫廷用品。
同时,马踏棋盘的规则设计也体现了中国古代的哲学思想,如阴阳、五行等。
第二点:马踏棋盘的策略与技巧马踏棋盘作为一种策略性棋类游戏,其胜负往往取决于玩家的策略和技巧。
在游戏中,玩家需要充分运用自己的智慧和思维,通过巧妙的布局和战术,来实现占领对方棋盘的目的。
首先,玩家需要掌握马踏棋盘的基本规则和棋子的行走方式。
马踏棋盘的棋子行走方式与象棋有所不同,马的移动方式是“日”字形,即每次移动可以横向或纵向移动一格,然后横向或纵向移动一格,类似于马的奔腾。
玩家需要熟练掌握马的行走方式,才能在游戏中更好地发挥其作用。
其次,玩家需要学会运用不同的战术和策略。
在马踏棋盘游戏中,玩家可以通过设置陷阱、封锁对方棋子、保护自己的棋子等方式来达到胜利的目的。
例如,玩家可以利用棋盘上的障碍物来设置陷阱,让对方棋子无法移动或被迫移动到不利的位置。
同时,玩家还需要保护自己的棋子,避免被对方轻易攻破。
最后,玩家需要具备良好的思维和应变能力。
在马踏棋盘游戏中,局势变化无常,玩家需要能够迅速分析局势,制定出合理的策略和方案。
同时,玩家还需要具备较强的应变能力,能够灵活应对各种突发情况,从而取得胜利。
数据结构课程设计(马踏棋盘)
中南民族大学数据结构课程设计报告姓名:康宇年级: 2010学号: 10061014专业:计算机科学与技术指导老师:宋中山2013年4月15日实习报告:2.4题 马踏棋盘题目:设计一个国际象棋的马踏棋盘的演示程序班级:计科一班 姓名:康宇 学号:10061014 完成日期:2013.4.15 一、需求分析1、国际象棋的马踏棋盘的功能是:将马随机放在国际象棋的N*N 棋盘board[N][N]的某个方格中,马按走棋规则进行移动。
要求每个方格只进一次,走遍棋盘上全部N*N 个方格。
编制非递归程序,求出马的行走路线,并按求出的行走路线,将数字1,2,...,N*N 依次填入一个N*N 的方阵,输出之。
2、测试数据:N 由读者指定。
马开始的位置也有读者指定(x,y ),1<=x<=N,1<=y<=N.3、实现提示:下图显示了N 为6,马位于方格(3,3),8个可能的移动位置。
一般来说,马位于位置(x ,y )时,可以走到下列8个位置之一。
但是,如果(x,y )靠近棋盘的边缘,上述有些位置可能超出棋盘范围,成为不允许的位置。
8个可能的位置可以用两个一维数组hi[0...7],hj[0...7]来表示:1 2 3 4 5 6二、概要设计为实现上述程序功能,应用栈Stack[Max*Max]来表示棋盘的行和列。
定义棋盘的规格N,马在下一步可以走的8个位置,hi[0...7],hj[0...7],用数组board[Max][Max]来标记棋盘,top 标记栈指针。
用户在输入了期盼的规格和起始坐标后,程序通过八个方向的探寻,123456输出第一个符合要求的棋盘,棋盘上显示了马每一步的位置,每一个位置只踏了一次,且踏遍棋盘。
1、元素类型(栈):struct Stack{int i; //行坐标int j; //列坐标} stack[Max][ Max];2、建立三个全局位置数组:int hi[8]={-2,-1,1,2,2,1,-1,-2};int hj[8]={1,2,2,1,-1,-2,-2,-1};用来存放下一个可能位置的横纵坐标;int board[Max][Max];用来标记棋盘。
数据结构课程设计马踏棋盘
数据结构课程设计-马踏棋盘目录1 前言 (1)2 需求分析 (1)2.1 任务和要求 (1)2.2 运行环境 (1)2.3 开发工具 (1)3 分析和设计 (1)3.1 系统分析及设计思路 (1)3.2 主要数据结构及算法 (2)3.3 函数流程图 (2)4 具体代码实现 (10)5 课程设计总结 (17)5.1 程序运行结果 (17)5.2 设计结论 (17)参考文献 (20)致谢 (20)1 前言编写一个C语言程序,作为国际象棋中的马踏遍棋盘的演示程序。
在这里,我们用一个main函数通过调用其他一些分功能函数来实现求并且输出马踏遍棋盘的行走路线。
2 需求分析2.1 任务和要求将马随机放在国际象棋的8×8棋盘的某个方格中,马按照走棋的规则进行移动。
每个方格只进入一次,走遍棋盘的全部64个方格。
编写算法,求出马的行走路线,并按求出的行走路线,将1,2,…,64依次填入一个8×8的方阵,并输出。
要求:画出算法的流程图,分析算法的时间复杂度。
2.2 运行环境(1)WINDOWS2000/XP系统(2)Visual C++ 6.0编译环境或TC编译环境2.3 开发工具C语言3 分析和设计3.1 系统分析及设计思路根据需求分析可知,我们所设计的程序要达到让马从任意一起点出发都不重复地遍历所有的8×8棋格的功能。
按照需求,并考虑到程序的可读性,我们按顺序共设计了以下六大模块:(1)定义头文件和宏定义模块:这是C程序必不可少的一个部分,通过头文件来调用程序所需库函数,而通过宏定义进行宏替换。
(2) 数据类型定义模块:该模块定义了全局数据结构,它们的作用域为从定义开始到本源文件结束,以便于让后面很多函数都可以用到它们,而不必再重新定义。
(3) 探寻路径函数模块:按照马的行走规则对棋盘进行遍历,寻找马的行走路径,每次仅访问一个棋格,保证每个棋格都访问到且每个棋格仅访问一次。
(4) 输出路径函数模块:对探寻路径函数模块中保存下来的顺序进行输出,输出格式按照棋盘8×8的方阵格式。
马踏棋盘——一个数据结构综合实验案例新解
总第 1 4卷 1 7期 5 21 0 2年 9月
大 众 科 技
P uar in e & Te h oo y op l e c Sc c n lg
Vo . 4 N0 9 L1 .
Se t pemb r 2 1 e 0 2
马踏 棋 盘
一 个 数 据 结构 综 合 实验 案 例 新解
知从 何 下 手 ,产 生 畏 难 心 理 ,会 打 击 学 生解 决 问题 的 自信 心 ;
而 案 例 过 于 简 单 , 则 达 不 到 综 合 实验 要 求 ,起 不 到锻 炼 学 生 的 目的 。一 个 合 适 的 综 合 实 验 案 例 ,应 该具 有 以 下几 个 特 点 :
课程打 下坚 实的基础 。然而 , 数据 结构也是一门理论性很强 的课程 ,理论 知识抽象 、概 念多 、算法 多而杂 ,学 生不好理 解 ,设 计程序无 从下手 。很 多学生反 映这 门课 “ 难懂 、不好 用 ”。学生不通 过实践很难对其 理论有深入 理解和应用 。因
Ab t a t I h sp p r t ep o lm f o s r v l g o h s b ad wa n r d c d i t a a s u t r x e me t e c i g a n s r c : n t i a e , h r b e o r eta ei n c e s o r si to u e n o d t t c u ee p r h n r i n a h n sa t
数据结构课内实验(栈和队列)
数据结构课内实验(栈和队列)西安邮电⼤学(计算机学院)数据结构课内实验报告实验名称:栈和队列专业名称:软件⼯程班级:软件⼯程xxxx班学⽣姓名:xxx学号(8位):xxxxxxxx指导教师:xx实验⽇期:xxxx年xx⽉xx⽇⼀.实验⽬的掌握栈和队列的逻辑结构和存储结构,以及栈和队列的基本算法,实现算法以及其应⽤⼆.实验内容马踏棋盘:将马随机地放在国际象棋8*8棋盘Board[8][8]的某个⽅格中,马按⾛棋规则进⾏移动,要求每个⽅格只进⾏⼀次,⾛遍整个棋盘的全部64个⽅格。
编制⾮递归程序,求出马的⾏⾛路线,并按求出的⾏⾛路线,将数字1,2,…,64依次填⼊⼀个8*8的⽅阵,输出之⼆.实验⽅案设计》1.基本思想:1)建⽴⼀个栈,定义其栈顶和栈底指针,以及栈的⼤⼩;2)将马的初始步压⼊栈中,计算其8个⽅向的权值,各点的8个⽅向按权值升序排列;3)马向最⼩权值⽅向⾏⾛,得到下⼀步,重复步骤2);4)某步的下⼀步超出棋盘,则应重新⾛,这⼀步出栈,由前⼀步重新选择⽅向;5)最后,根据栈中内容将马的⾏⾛路线填⼊⽅阵中,输出。
》2.函数说明:1.位置存储:typedef struct{ //每个坐标的位置int x; //x轴int y; //y轴}PosType;2.栈的存储信息:1. typedef struct{ //栈元素int ord;PosType seat; //位置int di; //马的⽅向(每个点都有8个⽅向可以选择,初始值为0,每使⽤⼀次⽅向给id++,它指向的是下⼀个该⾛的坐标位置,在函数Nextpos()和HorsePath()中会作为参数和变量⽤}ElemType;2.typedef struct{ //定义栈的结构ElemType *base; //base和top都是马每⾛⼀步存储的信息,不过base的信息类型都是为NULL//,top则存储真正的信息,base做为栈底的指针,top是栈顶指针ElemType *top;int stacksize;}SqStack3.各点的权值:weight[n][n] 描述该位置移动⽅向的个数4.存储待移动的⽅向,按升序移动Board[N][N][8]5.路径的存储path[N][N]》3.基本算法的实现1.IniStack();初始化栈其他栈操作省略2.Setweight()获取每个位置的权值,即可以移动的⽅向for(i=0;i{for(j=0;jweight[i][j]=0; //各点的权值for(k=0;k<8;k++){m=NextPos(elem.seat,k+1); //获取下次的坐标,有8个坐标可以择,if(m.x>=0&&m.x=0&&m.yweight[i][j]++; //(i,j)点有⼏个⽅向可以移动3.setmap()权值按照升序排列for(){for() NextPos(n2,h+1);//获取下个⽅位a[h]=weight[n1.x][n1.y];记录下个位置权值For() min=9 if(min>a[k]){min=a[k]; Board[i][j][m]=k; s=k; } a(s)=9;}4.NextPos(PosType curpos,int direction){switch() case1:... Case 2... ...}进⾏下次位置的查找5.HorsePath()创建马⾛过的路径并进⾏⼊栈和不合法位置的出栈操作{do{ if(pass(curpos) 位置是否合法{ push(elem)⼊站;board[x][y][id]+1; nextpos() 取得下⼀个节点} else{if(栈⾮空){while(栈⾮空且位置的8个⽅向已经⽤完){pop()出栈;Gettop() 取栈顶元素}if(还有⽅向没有⾛)Nextpos();读取下次的位置}}while(!StackEmpty())6.Outputpath() 输出⾛过的路径For(){ path[(*s1.base).seat.x][(*s1.base).seat.y]=i+1;++s1.base;}从栈底依次访问⾛过的位置,path元素从1开始标记,位置便是path的索引值,for(){printf(输出path的每个元素标记值)}三.该程序的功能和运⾏结果马踏棋盘:三.实验总结1.实验过程中遇到的问题及解决办法:开始时并不知道怎样去做这个程序,反复看了课本后开始对设计思路有了初步了解,建⽴⼀个位置(x,y),struct栈的信息和定义栈,每个栈需要存储马⾛过的位置,但怎样标记这些位置的先后顺序是⼀个很⼤的⿇烦,在创建⼀个路径,依次读取栈底位置并逐层从1开始标记就得到解决,之后碰到的最⼤问题是怎样将合法路径的压⼊栈内,⾸先要有⼀套规则,即⾛最⼩的路径,即权值,所以setweight()每个点的权值,setmap()函数存⼊到Board[][][]中(将下⼀步坐标按权值的⼤⼩排列),从输⼊的坐标开始读⼊下⼀步坐标并压⼊栈中,⽤while循环持续的压栈和出栈,知道所有的坐标都⾛完为⽌,2.实验中未完成的问题和已经完成的功能已经能够将马⾛过的每⼀步⼀⼀列举出来,但不能够完成多条⽅案的路径操作,输出界⾯也不够完善,缺少动态的功能3.对设计及调试过程的⼼得体会:整个代码的⼯作挺复杂的,算法有⼀定的难度。
1实验题目马踏棋盘
1:实验题目:马踏棋盘,2:实验目的:队列和栈的操作练习:3:实验具体内容:设计一个国际象棋的马踏遍棋盘的演示程序。
将马随机放在国际象棋8x8棋盘Board[8][8]的某个方格中,马按走棋规则进行移动。
要求每个方格只进入一次,走遍棋盘上全部64个方格。
编制非递归程序,求出马的行走路线,并按求出的行走路线,将数字1,2,…,64依次填入一个8x8的方阵,输出之。
矚慫润厲钐瘗睞枥庑赖賃軔。
4:数据结构算法思想:数据结构:简单的结构体和相关数组;算法思想:a :首先定义一个8*8的数组用于存放马的跳步过程;定义方向结点;b :获得马的第一个踩入点,调用findway()函数,该函数的while()语句将获得下一个要踩入的结点坐标,该过程调用pathnum()函数(注解:该函数给出了可踩入的所有结点各自的路径数目); 在findway()中,选择的要进入的下一个结点就是在pathway()中找到的结点(注解:该结点是可跳入的所有结的中路径最少的一个);聞創沟燴鐺險爱氇谴净祸測。
c : 在每步踩入前,将该结点的下标和踩入的次序做记录并输出;d : 读取最后一个结点的相关信息;5:模块划分:6:详细设计及运行结果:A:定义一个8*8的数组,用于存放每次踩入的结点位置;B:获取第一个踩入点;C:调用findway()函数Findway() 函数功能介绍:定义一个结点类型数组,用于存放8个下一步可踩入结点的信息;期间调用pathnum() 函数,该函数功能是记录所有下一个可踩入结点的可执行路径数目);选择下一个结点中路径最少的结点为下一个踩入的结点;在进入下一个踩入点前,先保存该结点的信息并输出,然后依次寻找下一个结点;残骛楼諍锩瀨濟溆塹籟婭骒。
D:寻找最后一个结点,并赋给相应信息;运行结果如下:7:调试情况,设计技巧和相关方法:A : 该开始想着利用栈的数据结构,记录回溯的相关信息,后来查资料发现如果每次入结点路径最少的那个结点,根本不会产生回溯的过程,后来就省去了栈队列的应用;酽锕极額閉镇桧猪訣锥顧荭。
马踏棋盘非递归算法
马踏棋盘非递归算法1. 引言马踏棋盘问题是一个经典的数学问题,也是一个典型的回溯算法应用。
问题描述为:在一个空白的 n x n 棋盘上,放置一个马,马按照国际象棋中的规则移动,即每次可向前、向后、向左、向右移动两步,并且再往左或往右移动一步,或者再往前或往后移动一步。
目标是使得马在不重复访问任何一个格子的情况下,遍历整个棋盘。
本文将介绍一种非递归算法来解决马踏棋盘问题。
该算法使用了深度优先搜索和回溯的思想,通过栈来实现非递归遍历。
2. 算法思路2.1 数据结构为了实现非递归遍历,我们需要使用栈来保存当前已经访问过的格子。
我们还需要使用一个二维数组来表示棋盘,并记录每个格子被访问过的次数。
2.2 算法流程1.初始化棋盘和栈。
2.将起始位置压入栈中,并将起始位置标记为已访问。
3.进入循环,直到栈为空:–从栈顶取出当前位置。
–判断是否遍历完成,如果是,则输出遍历路径并结束算法。
–否则,获取当前位置的可行移动方向。
–对于每个可行方向,判断下一步是否越界且未访问过。
•如果满足条件,则将下一步位置压入栈中,并标记为已访问。
4.如果循环结束仍未找到解,则输出”无解”。
3. 算法实现3.1 初始化棋盘和栈def init_board(n):board = [[0] * n for _ in range(n)]return boarddef init_stack():stack = []return stack3.2 获取可行移动方向def get_directions(x, y, n):directions = []moves = [(-2, 1), (-1, 2), (1, 2), (2, 1),(2, -1), (1, -2), (-1, -2), (-2, -1)] for dx, dy in moves:nx = x + dxny = y + dyif nx >= 0 and nx < n and ny >= 0 and ny < n: directions.append((nx, ny))return directions3.3 马踏棋盘非递归算法def knight_tour(n, start_x, start_y):board = init_board(n)stack = init_stack()stack.append((start_x, start_y))board[start_x][start_y] = 1while stack:x, y = stack[-1]if board[x][y] == n * n:print_solution(board)returndirections = get_directions(x, y, n)next_directions = []for nx, ny in directions:if board[nx][ny] == 0:next_directions.append((nx, ny))if next_directions:nx, ny = next_directions.pop(0)stack.append((nx, ny))board[nx][ny] = board[x][y] + 1else:board[x][y] = 0stack.pop()print("无解")3.4 输出遍历路径def print_solution(board):n = len(board)for i in range(n):for j in range(n):print(board[i][j], end='\t')print()4. 示例与分析我们以一个 5 x 5 的棋盘为例,从起始位置 (0, 0) 开始进行遍历。
数据结构课程设计 马踏棋盘求全部解及演示程序
安徽工程大学信息10 课程设计马踏棋盘的求解及演示设计摘要数据结构是计算机科学与技术专业的一门核心专业基础课程,是一门理论性强、思维抽象、难度较大的课程。
我认为学习数据结构的最终目的是为了获得求解问题的能力。
对于现实世界中的问题,我们应该能从中抽象出一个适当的数学模型,该数学模型在计算机内部用相应的数据结构来表示,然后设计一个解此数学模型的算法,再进行编程调试,最后获得问题的解答。
《数据结构》课程设计是计算机科学技术专业集中实践性环节之一,是学习完《数据结构》课程后进行的一次全面的综合练习。
开设本课程设计实践的主要目的就是要达到理论与实际应用相结合,提高学生的动手能力,完成计算机应用能力的培养;本课程设计主要解决马踏棋盘的问题,找出踏遍棋盘的多种路径,并实现动态要是过程。
马踏棋盘问题,实际上是图论中的哈密顿通路问题,是典型的NP问题,求解的问题与算法设计有很大关系,如果采取穷举搜索的话,很容易陷入海量搜索的状态,耗费巨大的时间,使问题几乎不可解,因此马在棋盘上遍历采用算法当中的深度优先算法和启发式贪心算法,用栈来存储遍历过程,通过对栈的使用实现对所有路径的搜索。
在调试过程发现,启发式贪心算法,针对于马踏棋盘问题有着极大的好处,就是无论从棋盘上哪个点开始,找到一条遍历完棋盘的通路是不需要回溯的,也就节省了大量的时间,而试探性的操作对于每个点都也只有168步,所以求出所有路径在不到一秒的时间内完成。
关键词:马踏棋盘;骑士周游;哈密顿通路;NP-完全问题;贪心算法;回溯法;目录马踏棋盘的求解及演示设计 (1)目录 (2)第一章引言 (3)第二章需求分析 (4)2.1问题描述 (4)2.2基本要求 (4)2.3具体需求 (4)2.4开发环境 (4)第三章概要设计 (5)3.1 系统概述 (5)3.2 系统描述 (6)3.3逻辑设计 (6)第四章详细设计 (7)4.1 功能模块设计 (7)4.2 数据结构设计 (7)4.3算法设计 (9)第五章调试与分析 (13)5.1 调试分析 (13)第六章系统试用说明 (14)6.1 系统试用说明 (14)第七章总结与体会 (14)参考文献 (15)第一章引言本课程设计主要研究马踏棋盘的问题,即骑士周游问题,是将马随机放在国际象棋的8×8棋盘的某个方格中,“马”按照走棋规则进行移动,要求每个方格只进入一次,走遍棋盘上全部64个方格。
数据结构教学规划马踏棋盘
前言学习数据结构的最终目的是解决实际的应用问题,特别是非数值计算类型的应用问题,数据结构课程设计就是为此目的一次实际训练。
要求我们在对题目进行独立分析的基础上,完成设计和开发,并最终接受严格的测试考核。
以深化对数据结构课程中基本概念、理论和方法的理解,提升综合运用所学知识处理实际问题的能力,使我们的的程序设计能力与调试水平有一个明显的提升。
课程设计所安排的题目,都有一定的难度和深度,从抽象数据类型的提炼、数据结构选择到算法的设计,均由我们每个人自主完成。
在一周的时间内,历经查找参考资料、使用技术手册、设计编码和撰写文档的实践,进一步升华对软件工程师和程序员人格素质的认识和理解。
本课程设计的主要设计内容是:设计一个马踏棋盘问题的演示程序。
即将马随机地放在国际象棋的8*8棋盘的某个方格中,然后令马按走棋规则开始进行移动。
要求马将棋盘上的每个方格进入且只进入一次,走遍全部64个方格。
要求编制非递归程序,求出马的行走路线,将数字1,2,…,64依次填入一个8*8的方阵在屏幕上显示输出。
针对该问题本课程设计采用的是面向对象的开发语言Java,在Windows7, myeclipse8.5.0的平台上开发出来,并有图形界面。
最终较好的实现了全部要求,达到了预期效果。
从中我也学到了很多,不仅仅是课堂外的新知识,还有那种会查资料,会学习新知识的能力。
这个课程设计的顺利完成,离不开胡老师的指导和帮助,在他的细心指导和帮助下,我对马踏棋盘程序开发的整个流程有了深刻地了解和系统地掌握,在这里学生表示真诚地感谢。
另外也谢谢这次课程设计提供给我帮助的同学们。
此外,本课程设计还参考了一些文献资料,在此向这些文献资料的作者深表谢意。
本课程设计可作为数据结构和Java课程教学的参考案例。
由于时间仓促和本人水平所限,设计中难免有不当和欠妥之处,敬请老师不吝批评指正。
笔者2016.6目录摘要 (3)第一章需求分析……………………………………………………………………………………………… (4)第二章概要设计 (5)2.1系统描述。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实现顺序栈或循环队列的存储一需求分析1.1理解栈的特性“后进先出”和队列的特性“先进先出”。
仅仅认识到栈和队列是两种特殊的线性表是远远不够的,本次实验的目的在于更深入的了解栈和队列的特性,以便在实际问题背景下灵活运用他们。
在了解他特性的基础上,还将巩固对这种结构的构造方法的理解。
1.2要求:在国际象棋8×8棋盘上面,按照国际象棋规则中马的行进规则,实现从任意初始位置,每个方格只进入一次,走遍棋盘上全部64个方格。
编制程序,求出马的行走路线,并按求出的行走路线,将数字1,2,…,64依次填入一个8×8的方阵,并输出它的行走路线(棋盘如图所示)。
输入:任意一个起始位置;输出:无重复踏遍棋盘的结果,以数字1-64表示行走路线。
二概要设计为了实现上述程序功能,可以采用顺序栈或者链栈来存储它的数据,本实验所需要的存储空间不是很大,不需动态的开辟很多空间,所以采用相对简单的顺序栈来存储数据,既方便有简单,而用链栈在实现上相对比顺序栈复杂的一点。
2.1顺序栈的抽象数据类型定义:ADT Stack{数据对象:D={ai| ai∈(0,1,…,9),i=0,1,2,…,n,n≥0}数据关系:R={< ai-1, ai >| ai-1, ai∈D,i=1,2,…,n} } ADT Stack2.2本程序包含三个模块:1、主程序模块:void main(){定义变量;接受命令;处理命令;退出;}2、起始坐标函数模块——马儿在棋盘上的起始位置;3、探寻路径函数模块——马儿每个方向进行尝试,直到试完整个棋盘;4、输出路径函数模块——输出马儿行走的路径;2.3各模块之间的调用关系:三详细设计3.1定义头文件和预定义#include<stdio.h>#define MAXSIZE 100#define N 83.2数据类型定义int board[8][8]; //定义棋盘int Htry1[8]={1,-1,-2,2,2,1,-1,-2};/*存储马各个出口位置相对当前位置行下标的增量数组*/ int Htry2[8]={2,-2,1,1,-1,-2,2,-1};/*存储马各个出口位置相对当前位置列下标的增量数组*/struct Stack{ //定义栈类型int i; //行坐标int j; //列坐标int director; //存储方向}stack[MAXSIZE]; //定义一个栈数组int top=-1; //栈指针3.3函数声明void InitLocation(int xi,int yi); //马儿在棋盘上的起始位置坐标int TryPath(int i,int j); //马儿每个方向进行尝试,直到试完整个棋盘void Display(); //输出马儿行走的路径3.4起始坐标函数模块void InitLocation(int xi,int yi){int x,y; //定义棋盘的横纵坐标变量top++; //栈指针指向第一个栈首stack[top].i=xi; //将起始位置的横坐标进栈stack[top].j=yi; //将起始位置的纵坐标进栈stack[top].director=-1; //将起始位置的尝试方向赋初值board[xi][yi]=top+1; //标记棋盘x=stack[top].i; //将起始位置的横坐标赋给棋盘的横坐标y=stack[top].j; //将起始位置的纵坐标赋给棋盘的纵坐标if(TryPath(x,y)) //调用马儿探寻函数,如果马儿探寻整个棋盘返回1否则返回0 Display(); //输出马儿的行走路径elseprintf("无解");}3.5探寻路径函数模块int TryPath(int i,int j){int find,director,number,min;//定义几个临时变量int i1,j1,h,k,s; //定义几个临时变量int a[8],b1[8],b2[8],d[8];//定义几个临时数组while(top>-1) //栈不空时循环{for(h=0;h<8;h++) //用数组a[8]记录当前位置的下一个位置的可行路径的条数{number=0;i=stack[top].i+Htry1[h];j=stack[top].j+Htry2[h];b1[h]=i;b2[h]=j;if(board[i][j]==0&&i>=0&&i<8&&j>=0&&j<8) //如果找到下一位置{for(k=0;k<8;k++){i1=b1[h]+Htry1[k];j1=b2[h]+Htry2[k];if(board[i1][j1]==0&&i1>=0&&i1<8&&j1>=0&&j1<8)//如果找到下一位置number++; //记录条数}a[h]=number; //将条数存入数组a[8]中}}for(h=0;h<8;h++) //根据可行路径条数小到大按下表排序放入数组d[8]中{min=9;for(k=0;k<8;k++)if(min>a[k]){min=a[k];d[h]=k; //将下表存入数组d[8]中s=k;}a[s]=9;}director=stack[top].director;if(top>=63) //如果走完整个棋盘返回1return (1);find=0; //表示没有找到下一个位置for(h=director+1;h<8;h++) //向八个方向进行探寻{i=stack[top].i+Htry1[d[h]];j=stack[top].j+Htry2[d[h]];if(board[i][j]==0&&i>=0&&i<8&&j>=0&&j<8) //如果找到下一位置{find=1; //表示找到下一个位置break;}}if(find==1) //如果找到下一个位置进栈{stack[top].director=director; //存储栈结点的方向top++; //栈指针前移进栈stack[top].i=i;stack[top].j=j;stack[top].director=-1; //重新初始化下一栈结点的尝试方向board[i][j]=top+1; //标记棋盘}else //否则退栈{board[stack[top].i][stack[top].j]=0; //清除棋盘的标记top--; //栈指针前移退栈}}return (0);}3.6输出路径函数模块void Display(){int i,j;for(i=0;i<N;i++){for(j=0;j<N;j++)printf("\t%d ",board[i][j]); //输出马儿在棋盘上走过的路径printf("\n\n");}printf("\n");}3.7主程序模块void main(){int i,j;int x,y;for(i=0;i<N;i++) //初始化棋盘for(j=0;j<N;j++)board[i][j]=0;for(;;){printf("Please input importpoint(1<=x<=8 and 1<=y<=8)\n");printf("Input x = ");scanf("%d",&x); //输入起始位置的横坐标printf("Input y = ");scanf("%d",&y); //输入起始位置的纵坐标if(x>=1&&x<=8&&y>=1&&y<=8)break;printf("Your input is worng\n");}printf("begin with %d board:\n\n", 8*(x-1)+y);InitLocation(x-1,y-1); //调用起始坐标函数}四调试分析(1)本次实验的主要目的是在于掌握和理解栈的特性和它的应用。
在编制该程序中遇到了很多问题。
首先,在开始刚编制程序的时候遇到的问题是,程序编译都通不过,主要在一些细节的问题上,还有在程序的返回值在刚开始时也没有正确返回。
经过编译慢慢调试,编译都能通过,没有错误和警告。
(2)虽然编译都能通过,但是运行时却出错,程序不能终止,只有通过人工方式结束程序,可能是在某些地方出现了无限死循环了,然后在仔细检查代码,发现没有标记马儿尝试的方向director,这样的话,马儿回溯的时候,下一次又有可能走那个方向,这样就出现了死循环。
(3)标记好马儿尝试的方向后,编译运行,但是运行结果却不符合程序所要求的结果,说明在算法上肯定有错误,检查发现,马儿走的坐标没有控制后,它的横纵坐标必须控制0到7之间,否则的话马儿就会踏出棋盘以外,这样输出的结果就不对。
还有就是棋盘走过的位置要标记一下,以便下次走不重复走,当回溯的时候的记得把标记给清掉,这个地方有时候也很容易混淆。
(4)还有一点就是,该程序运算量大,算法复杂度高,所以运行的时候很慢,特别占内存,CPU的使用也很高,几乎都在70%到90%之间,配置低了可能还运行不了。
五测试结果结果1:结果2:六实验体会通过本次实验的编写,能够掌握栈的性质以及它的应用。
这次实验花了很多时间才完成,其实本应该早完成的,在检查的过程中有多多少少修改完美了一下,不过算法思想却没有改变。
这个程序也让我头疼了几次,就是运行速度很慢,要等很久才能输出结果,这样的话很占内存资源,而且CPU的使用记录也很高,主要是它需要的运算太多,所以CPU 使用记录也是很高的。
虽然我也参考了一些优化的算法,可以找到最优路进走,但是这些最优算法都和栈的应用失去了联系,本次的实验主要目的就是要了解栈,所以不用栈来写该程序就失去了该实验的意义。
在该程序的编制过程中留下了一些思考的问题,就是马儿从一个起点位置开始探寻,最后马儿探寻成功的路径会不会是不只一条路径,可能还有多条路径,由于时间和精力的限制没有去深究,但是这应该值的思考的。