八皇后问题.docx
《八皇后问题.docx》由会员分享,可在线阅读,更多相关《八皇后问题.docx(16页珍藏版)》请在冰点文库上搜索。
八皇后问题
安徽省巢湖学院计算机与信息工程学院
课程设计报告
课程名称《数据结构》
课题名称八皇后问题
专业计算机科学与技术
班级
学号
姓名
联系方式
指导教师
2011年12月25日
目录
1、数据结构课程设计任务书1
1.1、题目1
1.2、要求1
2、总体设计1
2.1、功能模块设计1
2.2、所有功能模块的流程图1
3、详细设计1
3.1、程序中所采用的数据结构及存储结构的说明1
3.2、算法的设计思想2
3.3、稀疏矩阵各种运算的性质变换2
4、调试与测试:
2
4.1、调试方法与步骤:
2
4.2、测试结果的分析与讨论:
3
4.3、测试过程中遇到的主要问题及采取的解决措施:
3
5、时间复杂度的分析:
4
6、源程序清单和执行结果4
7、C程序设计总结8
8、致谢8
9、参考文献8
1、数据结构课程设计任务书
1.1、题目
八皇后问题
1.2、要求
编写程序实现将八个皇后放置在国际象棋棋盘的无冲突的位置上的算法,并给出所有的解。
2、总体设计
本课件学生是用循环递归循环来实现的,分别一一测试了每一种摆法,并把它拥有的92种变化表现出来。
在这个程序中,我的主要思路以及思想是这样的:
1)解决冲突问题:
这个问题包括了行,列,两条对角线;
列:
规定每一列放一个皇后,不会造成列上的冲突;
行:
当第I行被某个皇后占领后,则同一行上的所有空格都不能再放皇后,要把以I为下标的标记置为被占领状态;
对角线:
对角线有两个方向。
在这我把这两条对角线称为:
主对角线和从对角线。
在同一对角线上的所有点(设下标为(i,j)),要么(i+j)是常数,要么(i-j)是常数。
因此,当第I个皇后占领了第J列后,要同时把以(i+j)、(i-j)为下标的标记置为被占领状态。
2)数据结构的实现
而对于数据结构的实现,学生则是着重于:
数组a[I]:
a[I]表示第I个皇后放置的列;I的范围:
1..8;
对角线数组:
b[j](主对角线),c[j](从对角线),根据程序的运行,去决定主从对角线是否放入皇后;
2.1、功能模块设计
根据课程设计题目的功能要求,各个功能模块的组成框图如下:
2.2、所有功能模块的流程图
皇后模块流程图
八皇后递归流程图
3、详细设计
模块功能说明:
如函数功能、入口及出口参数说明,函数调用关系描述等;
皇后模块算法:
画皇后图象,然后存储到缓冲区
八皇后摆放方法模块:
八皇后的递归算法
初始化模块:
初始化
3.1、程序中所采用的数据结构及存储结构的说明
数据结构的实现:
数组a[i]:
a[i]表示第i个皇后放置的列;i的范围:
1-8;对角线数组:
b[j](主对角线),c[j](从对角线),根据程序的运行,去决定主从对角线是否放入皇后;然后进行数据的初始化。
从n列开始摆放第n个皇后(因为这样便可以符合每一竖列一个皇后的要求),先测试当前位置(n,m)是否等于0(未被占领):
如果是,摆放第n个皇后,并宣布占领(切记要横列竖列斜列一起来),接着进行递归;如果不是,测试下一个位置(n,m+1),但是如果当n<=8,m=8时,却发现此时已经无法摆放时,便要进行回溯。
3.2、算法的设计思想
本程序通过对子函数voidqu(inti)的调用,将八皇后的问题关键通过数据结构的思想予以了实现。
虽然题目以及演算看起来都比较复杂,繁琐,但在实际中,只要当一只皇后放入棋盘后,在横与列、斜线上没有另外一只皇后与其冲突,再对皇后的定位进行相关的判断。
即可完成。
如果在这个程序中,我们运用的是非递归的思想,那么将大量使用if等语句,并通过不断的判断,去推出答案,而且这种非递归的思想,大大的增加了程序的时间复杂度。
如果我们使用了数据结构中的算法后,那么程序的时间复杂度,以及相关的代码简化都能取得不错的改进。
这个程序,我运用到了数据结构中的栈、数组,以及树和回溯的方法。
特别是在对于树以及二叉树的学习,更是为八皇后的问题提供了科学的解决方案,通过对树的分析,把八皇后的问题看成了树,而在衍生第一个变化后,上面的第一层八个变化就变成了八个结点,而这八个结点再继续的衍生……,这样比较形象的将八皇后的问题简单化了。
然后再通过回溯法进行设计,回溯法是设计递归过程的一个重要的方法。
它的求解过程实质上是一个先序遍历一棵“状态树“的过程。
在这个程序设计中,它先进行判断,棋盘上是否已经得到一个完整的布局(即棋盘是否已经摆上8个棋子),如果是,则输出布局;如果不是则依次先根遍历满足约束条件的各棵子树,流程即是:
判断该子树根的布局是否合法:
如果合法的话,则先根遍历该子树;如果不合法的话,则剪去该子树的分支。
3.3、稀疏矩阵各种运算的性质变换
4、调试与测试:
4.1、调试方法与步骤:
4.2、测试结果的分析与讨论:
(测试要写出测试用例及每个用例结果的的截图)
通过编译连接后,程序基本上把八皇后的92种摆法的都进行了演示;但程序运行中也出现了以下缺点:
因为八皇后的表现方法甚多,输出后虽能全部显示,但未能使屏幕停留,把一个一个的将其显示出来,但是这样便使得操作步骤太多,也会造成不必要的麻烦!
所以只画出了第一种和最后一种的输出结果,演示如图所示:
正确输出结果如下:
4.3、测试过程中遇到的主要问题及采取的解决措施:
5、时间复杂度的分析:
6、源程序清单和执行结果
(清单中应有足够的注释)
【示例1】
#include
#include
#include
#include
#include
void*buff1,*buff2;
typedefstruct
{
intA[21],B[21],C[21],Y[8];
}
Queen;
voidSetQueen(Queen*Q)/*初始化*/
{
inti;
for(i=0;i<21;i++)
{
Q->A[i]=0;
Q->B[i]=0;
Q->C[i]=0;
}
for(i=0;i<8;i++)
Q->Y[i]=-1;
}
voidQueenPic(void)/*画皇后图象,然后存储到缓冲区*/
{
intsize,
polypoints1[10]={9,1,11,1,20,20,1,20,9,1},
polypoints2[10]={29,1,31,1,40,20,21,20,29,1};
setfillstyle(SOLID_FILL,LIGHTBLUE);/*画淡蓝色棋格*/
setcolor(LIGHTBLUE);
rectangle(1,1,20,20);
floodfill(10,10,LIGHTBLUE);
setfillstyle(SOLID_FILL,WHITE);/*画白色棋格*/
setcolor(WHITE);
rectangle(21,1,40,20);
floodfill(30,10,WHITE);
setfillstyle(SOLID_FILL,DARKGRAY);
setcolor(YELLOW);
drawpoly(5,polypoints1);
drawpoly(5,polypoints2);
floodfill(10,10,YELLOW);
floodfill(30,10,YELLOW);
size=imagesize(1,1,20,20);/*计算缓冲区大小,然后存储*/
buff1=(void*)malloc(size);
buff2=(void*)malloc(size);
getimage(1,1,20,20,buff1);
getimage(21,1,40,20,buff2);
cleardevice();
}
voidChecker(void)/*画棋盘函数*/
{
inti,k;
for(k=0;k<8;k++)
for(i=0;i<8;i++)
if(k%2==0&&i%2==0||k%2!
=0&&i%2!
=0)
{
setfillstyle(SOLID_FILL,LIGHTBLUE);
setcolor(LIGHTBLUE);
rectangle(i*20,20+k*20,(i+1)*20,20+(k+1)*20);
floodfill(i*20+10,20+k*20+10,LIGHTBLUE);
}
else
{
setfillstyle(SOLID_FILL,WHITE);
setcolor(WHITE);
rectangle(i*20,20+k*20,(i+1)*20,20+(k+1)*20);
floodfill(i*20+10,20+k*20+10,WHITE);
}
}
voidPrintQueen(Queen*t)/*图形输出函数*/
{intk;
charstr[20];
statictotal=0;
total++;
setviewport(240,80,400,260,1);/*设置窗口*/
sprintf(str,"NO.%d",total);
setcolor(GREEN);
settextstyle(0,0,1);
outtextxy(0,0,str);
Checker();
for(k=0;k<8;k++)
if(k%2==0&&t->Y[k]%2==0||k%2!
=0&&t->Y[k]%2!
=0)
putimage((t->Y[k])*20,20+k*20,buff1,COPY_PUT);
else
putimage((t->Y[k])*20,20+k*20,buff2,COPY_PUT);
getch();
if(getch()==27)exit(0);
clearviewport();}
voidQueenRe(Queen*Q,inty)/*八皇后的递归算法*/
{intx;
if(y>7)
return;
for(x=0;x<8;x++)
if(!
Q->A[x+7]&&!
Q->B[x+y+7]&&!
Q->C[x-y+7])/*下一棵要遍历的子树由状态数确定*/
{Q->Y[y]=x;
Q->A[x+7]=1;
Q->B[x+y+7]=1;
Q->C[x-y+7]=1;
if(y==7)
PrintQueen(Q);
QueenRe(Q,y+1);/*进入下一层递归*/
Q->A[x+7]=0;
Q->B[x+y+7]=0;
Q->C[x-y+7]=0;}
}
voidmain(void)
{
QueenQ;
intgdriver=DETECT,gmode;
initgraph(&gdriver,&gmode,"D:
//Win-TC");
SetQueen(&Q);
setcolor(YELLOW);
QueenPic();
cleardevice();
setcolor(LIGHTGREEN);
settextstyle(0,0,3);
outtextxy(180,10,"EightQueens");
setcolor(WHITE);
settextstyle(0,0,1);
outtextxy(250,400,"2009.11.83:
30pm");
QueenRe(&Q,0);
getch();
closegraph();
}
.
.
.
.
.
第92
7、C程序设计总结
《数据结构》是计算机专业很重要的一门课程,也是必须要熟练掌握的课程,这次的课程设计对我的数据结构知识进行了一次全面的综合训练,加深了对数据结构基本概念和基本知识的理解,巩固了课堂上学的知识,掌握了数据结构的一些基本方法,深刻理解了算法,锻炼了自己分析问题解决问题的能力。
8、致谢
能够完成这次课程设计必须感谢^^(他帮我修改了几处重要错误,同时启发我完善了该程序的功能)。
9、参考文献
吕凤哲C++语言程序设计(第二版)北京:
电子工业出版社,2005
耿国华数据结构——C语言描述西安电子科技大学出版社
苏仕华数据结构课程设计北京:
机械工业出版社,2005.5
严蔚敏数据结构北京:
清华大学出版社,1997