数据结构课程设计之八皇后问题.docx

上传人:b****8 文档编号:30443829 上传时间:2023-08-15 格式:DOCX 页数:21 大小:118.20KB
下载 相关 举报
数据结构课程设计之八皇后问题.docx_第1页
第1页 / 共21页
数据结构课程设计之八皇后问题.docx_第2页
第2页 / 共21页
数据结构课程设计之八皇后问题.docx_第3页
第3页 / 共21页
数据结构课程设计之八皇后问题.docx_第4页
第4页 / 共21页
数据结构课程设计之八皇后问题.docx_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

数据结构课程设计之八皇后问题.docx

《数据结构课程设计之八皇后问题.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计之八皇后问题.docx(21页珍藏版)》请在冰豆网上搜索。

数据结构课程设计之八皇后问题.docx

数据结构课程设计之八皇后问题

注意:

本文编程使用c++!

c语言编程在最后!

目录

一、需求分析1

二、概要设计3

三、详细设计5

四、调试分析及测试8

五、个人工作及创新12

六、小结12

参考文献13

附录13

一、需求分析

八皇后问题是一个古老而著名的问题,该问题是十九世纪著名的数学家高斯1850年提出的,并作了部分解答。

高斯在棋盘上放下了八个互不攻击的皇后,他还认为可能有76种不同的放法,这就是有名的“八皇后”问题。

在国际象棋中,皇后是最有权利的一个棋子;只要别的棋子在它的同一行或同一列或同一斜线(正斜线或反斜线)上时,它就能把对方棋子吃掉。

所以高斯提出了一个问题:

在8*8的格的国际象棋上摆放八个皇后,使其不能相互攻击,即任意两个皇后都不能处于同一列、同一行、或同一条斜线上面,问共有多少种解法。

现在我们已经知道八皇后问题有92个解答。

 

1.1涉及到的知识点

本次课程设计中,用到的主要知识有:

递归法、回溯法的应用,for语句的灵活运用,数据结构中树知识的灵活运用、栈及数组的掌握.

下面给出八皇后问题回溯算法的伪代码

PlaceQueen(row)

for第row行的各列col

If位置(row,col)可以放置皇后

在位置(row,col)放置一个皇后

If(row<9)

PlaceQueen(row+1);

else

成功,打印棋盘

将位置(row,col)上的皇后取走,尝试下一列位置//回溯

其中回溯法的应用如下:

回溯法也是设计递归过程的一种重要方法,原理或步骤为:

试着先把第一个皇后放在棋盘上,然后再放第二个,使两个皇后不会互相攻击,再放第三个皇后,使得她与前面两个皇后都不会互相攻击,依此类推,直至所有的皇后都放上去。

如果第七个皇后放上后,第八个皇后已经没有安全的位置可以放置,则试着调试第七个皇后的位置,再尝试第八个皇后有没有安全的位置;如果第七个皇后的所有安全位置都已尝试过了,第八个皇后还是没有安全的位置,则试着调试第六个皇后的位置,重新放置第七、八个皇后的尝试。

如此类推,最糟糕的事情就是一直到将第一个皇后的位置进行调整。

1.2功能要求

当运行程序时,在屏幕上显示每一种方法八个皇后的相对位置,要用比较直观的界面显示。

进入界面后,就会提示输入字符串的输入形式,在八皇后求解程序中,只要你选择输出解的格式,选择1则显示为每一列皇后的放置的行数,,选择2则显示的是以矩阵形式形象的显示皇后的放置位置,选择0则退出程序的调试。

在调试结果中,1的位置也就表示了该皇后应该所在的位置,0代表了空位置。

二、概要设计

2.1数据结构

1.解数组a,a[i]表示第i个皇后放置的列,范围为1~8。

2.行冲突标记数组b,b[j]=0表示第j行空闲,b[j]=1表示第j行被占领,范围为1~8。

3.对角线冲突标记数组c、d。

c[i-j]=0表示第(i-j)条对角线空闲,c[i-j]=1表示第(i-j)条对角线被占领,范围-7~7。

d[i+j]=0表示第(i+j)条对角线空闲,d[i+j]=1表示第(i+j)条对角线被占领,范围2~16。

2.2抽象数据类型的定义

Print()//打印每一列皇后的放置的行数以及以矩阵形式形象的显示皇后的放置位置

JudgeQueen1()//递归寻找摆放皇后位子

voidmain()//主函数调用

2.3算法流程

1.数据初始化。

2.从n列开始摆放第n个皇后(因为这样便可以符合每一竖列一个皇后的要求),先测试当前位置(n,m)是否等于0(未被占领)。

如果是,摆放第n个皇后,并宣布占领(记得姚横列竖列斜列一起设置),接着进行递归;如果不是,测试下一个位置(n,m+1),但是如果当n<=8,m=8时,发现此时已无法摆放时,便要进行回溯。

从问题的某一种可能出发,搜索从这种情况能出发,继续搜索,这种不断“回溯”的寻找解的方法,称为“回溯法”。

3.当n>8时,便打印出结果。

其算法流程图如下:

测试下个位置

m=m+1

NY

摆放皇后,并

宣布占领

 

YN

三、详细设计

//定义数组

inta[8]//表示第i个皇后放置的列,范围为1~8。

intb[8]//表示第j行空闲,b[j]=1表示第j行被占领,范围为1~8

intc[30]//表示第(i-j)条对角线空闲,c[i-j]=1表示第(i-j)条对角线被占领,范围-7~7

intd[30]//表示第(i+j)条对角线空闲,d[i+j]=1表示第(i+j)条对角线被占领,范围2~16。

//位置标明法打印

voidprint1()

{

X++;

cout<<"\tNo."<

";//每一行皇后放置的列数的第X种情况

for(k=1;k<9;k++)

cout<<""<<""<

cout<<"\n";

}

//矩阵表示法打印

voidprint2(){

intt,n;

Y++;

cout<<"\tNo."<

\n\t";//矩阵形式的第Y种情况

for(k=1;k<9;k++)

{

n=a[k];

for(t=1;t

cout<<"0";

cout<<"1";

t++;

for(t;t<9;t++)

cout<<"0";

cout<<"\n\t";

}

cout<<"\n";

}

//回溯递归法摆放皇后

voidPlaceQueen1(inti)

{

intj;

for(j=1;j<9;j++)//每个皇后都有8种可能位置

{

if((b[j]==0)&&(c[i+j]==0)&&(d[i-j]==0))//判断位置是否冲突

{

a[i]=j;//摆放皇后

b[j]=1;//宣布占领第J行

c[i+j]=1;//占领两个对角线

d[i-j]=1;

if(i<8)

PlaceQueen1(i+1);//8个皇后没有摆完,递归摆放下一皇后

else

print1();//完成任务,打印结果

b[j]=0;//回溯

c[i+j]=0;

d[i-j]=0;

}

}

}

voidPlaceQueen2(inti)

{

intj,e=1;

for(j=1;j<9;j++)

{

if((b[j]==0)&&(c[i+j]==0)&&(d[i-j]==0))

a[i]=j;

b[j]=1;

c[i+j]=1;

d[i-j]=1;

if(i<8)

PlaceQueen2(i+1);

else

print2();//打印结果

b[j]=0;//回溯

c[i+j]=0;

d[i-j]=0;

e++;

}

}

}

//调用主函数

voidmain()

{

……

cout<<"\n\n\t**WelcometoEightQueeninquiriessoftwareproblems**\n\n";

for(k=0;k<24;k++)//数据初始化

{b[k]=0;c[k]=0;d[k]=0;

}

ch='y';

while(ch=='y'||ch=='Y')

{

cout<<"\n\t查询菜单\n";

cout<<"\n\t******************************************************";

cout<<"\n\t*No.1--------每一行皇后放置的列数的情况*";

cout<<"\n\t*No.2--------视图矩阵形式显示皇后的位置*";

cout<<"\n\t*No.0--------退出*";

cout<<"\n\t******************************************************";

cout<<"\n\t请选择菜单号(No.0--No.2):

";

cin>>choice;

switch(choice)

{

case1:

cout<<"\n\t每一行皇后放置的列数的情况\n\n";

PlaceQueen1

(1);//从第1个皇后开始放置

break;

case2:

cout<<"\n\t使用回车查看下一种情况\n\n";;

PlaceQueen2

(1);//从第1个皇后开始放置

break;

case0:

ch='n';

break;

default:

cout<<"\n\t\t菜单选择错误,请重新输入!

\n";

}

}

}

 

四、调试分析及测试

4.1遇到的问题及解决方法

(1).由于对八个皇后放置的位置不能一次确定,而且前一个皇后的放置位置直接影响着后面的放置位置,使程序调试时要花费不少时间。

(2).本程序有些代码重复出现,显得程序的有些代码看起来很杂乱。

但其中最主要的问题是逻辑错误导致程序死循环或不循环或循环一小部分,但是编译时却没有错误,就是没有正确的输出答案。

比如说,在voidprint2()中有for(t;t<9;t++),如果赋t=1,则在视图显示法中会出现排序紊乱。

类似的还有出现死循环的问题,后在同学和老师的帮助下,经细心改正后才把调试工作做完。

(3).这里在编写回溯算法时候需要特别注意以下几点:

•  回溯循环的结束在于第一个皇后被回溯。

•  当找到一个解时,需要复制整个棋盘,不然接下来的回溯将破坏已经找到的解。

•  找到一个解后,需要在当前皇后的基础上回溯。

•  回溯一个皇后时,要对当前的列数进行重置。

一般在编写完核心代码后,需要编写一定的测试代码进行单元测试。

否则的话,后面出现的错误的程序代码问题是好难修正的!

4.2算法的时空分析

该算法的运行时间和和皇后的放置方法成正比,在最好情况下的时间和空间复杂度均为O

(1),在最差情况下均为O(n*n),平均情况在它们之间。

4.3程序模块构架

本程序模块划分比较合理,且利用指数组存储棋盘,操作方便。

至于整体的系统架构,为了简单起见,这样的系统可以分成两个模块,第一个模块是负责模拟问题、提供算法,而另外一个模块则致力于窗口演示,是一个窗体应用程序

4.4算法的改进

这道题可以用非递归循环也可以用递归循环的方法来做,这里我用了后者,其方法是分别一一测试每一种皇后摆法,直到得出正确的答案即所谓的回溯法。

4.5程序使用说明

(1)本程序的运行环境为DOS操作系统

(2)进入演示程序后即显示文本方式的用户界面

(3)进入界面后,就会提示输入字符串的输入形式,在八皇后求解程序中,只要你选择输出解的格式,选择1则显示为每一列皇后的放置的行数,,选择2则显示的是以矩阵形式形象的显示皇后的放置位置,选择3则退出程序的调试。

在调试结果中,1的位置也就表示了该皇后应该所在的位置,0代表了空位置。

 

4.6测试结果

初步运行界面

位置标明每一行皇后放置的列数

视图矩阵形式显示皇后位置

五、个人工作及创新

在本次课程设计的学习过程中,我在其中的最大的收获,就是得到了许多的经验以及软件设计的一些新的思路.

迈着时间的步伐,这次的课程设计也即将结束,但这个学期数据结构的学习还是具有相当大的意义,特别是这次的课程设计,它从一个程度上改变了我们的编程思想,如何将一个程序快速而又准备的进行编写,进行编译,都成为了我思考的重点,也通过这一个学期的学习,我们将数据结构的思想带入到了我们以后的编程学习中去。

在这个阶段,我也明白了,好的思想,不能提留于字面上的认知,还需要的是平时多练多写一些相关的程序,并且通过修改,加入新的算法去尝试改变自己的一些编程思想。

保持更新算法的速度,这才是关键。

比如说,八皇后在变成初期,由于不自觉的采用了非递归的算法,结果大大增加了程序的复杂程度,并且也让整个程序的时间复杂度变得更大.

在这次的八皇后问题中可以用概率算法,也可以采用传统的递归算法,这里我用了后者.而且还用到了回溯法.回溯法是允许我们在尝试某些选择失败后,能系统的尝试完所有可能的选择。

在八皇后问题中越早放置的皇后,她的选择就越多;而越晚放置的皇后,她的选择就越少。

八皇后问题和迷宫问题是很相似的,因此,若采用回溯,将能很好很快而且高效率的解决问题。

这便是在这次的一些创新之处!

当然还可以设计N皇后问题,基本思想不变

六、小结

通过这次的课程设计,我从中得到了许多经验和软件设计的一些新思路;从这个八皇后问题设计以及分析中,本人从中理解到了数据结构对于软件设计的重要性,它的使用,可以改变软件的运行周期,思路从繁化简,并且都能够通过其相关引导,将本身以前编程思想进行扩充,发展.这也是在这次课程设计中我所掌握得到的。

但在这次的课设中也遇了一些问题,如,八皇后在变成初期由于没真正体会到“树”在里面的运用,不自觉的采用了非递归的算法,结果大大增加了程序的复杂程度。

并且也让整个程序的时间复杂度变得更大;在重温了树的回溯,以及二叉树的遍历后,最终将程序进行了一次较大的改造。

并且通过思考,再将以前的数组知识加以运用才最终解决了这个问题,整个程序的算法的可看性也有了较大的改进。

参考文献

[1].黄晓霞,萧蕴诗.数据挖掘应用研究及展望[J].计算机辅助工程.2001.4:

23-29

[2].黄解军,潘和平,万幼川.数据挖掘技术的应用研究.计算机工程与应用,2003,02:

45~48.

[3].吕凤哲,C++语言程序设计(第二版).北京:

电子工业出版社,2005

[4].耿国华等著,数据结构——C语言描述,西安电子科技大学出版社

[5].苏仕华,数据结构课程设计.-北京:

机械工业出版社,2005.5

[6].严蔚敏,吴伟民,数据结构.北京:

清华大学出版社,1997

附录

致谢

在这次课程设计中,我遇到了不少问题,包括程序和课程设计的撰写上的,同学老师给了我许多帮助,在此我表示对你们的忠心感谢。

同时,学校给了我做课程设计的很好的条件,我才能够顺利的完成,在此,我仅以文字的形式表示忠心感谢,感谢您们对我的帮助。

#include

inta[8],b[8],c[30],d[30];

inti,k,X=0,Y=0;

voidprint1()

{

X++;

printf("\tNo.%d",X);//每一行皇后放置的列数的第X种情况

for(k=1;k<9;k++)

printf("%d",a[k]);

printf("\n");

}

voidprint2()

{

intt,n;

Y++;

printf("\tNo.%d",Y);//矩阵形式的第Y种情况

printf("\n\t");

for(k=1;k<9;k++)

{

n=a[k];

for(t=1;t

printf("0");

printf("1");

t++;

for(t;t<9;t++)

printf("0");

printf("\n\t");

}

printf("\n");

}

voidPlaceQueen1(inti)

{

intj;

for(j=1;j<9;j++)//每个皇后都有8种可能位置

{

if((b[j]==0)&&(c[i+j]==0)&&(d[i-j]==0))//判断位置是否冲突

{

a[i]=j;//摆放皇后

b[j]=1;//宣布占领第J行

c[i+j]=1;//占领两个对角线

d[i-j]=1;

if(i<8)

PlaceQueen1(i+1);//8个皇后没有摆完,递归摆放下一皇后

else

print1();//完成任务,打印结果

b[j]=0;//回溯

c[i+j]=0;

d[i-j]=0;

}

}

}

voidPlaceQueen2(inti)

{

intj,e=1;

for(j=1;j<9;j++)

{

if((b[j]==0)&&(c[i+j]==0)&&(d[i-j]==0))

{

a[i]=j;

b[j]=1;

c[i+j]=1;

d[i-j]=1;

if(i<8)

PlaceQueen2(i+1);

else

print2();//打印结果

b[j]=0;//回溯

c[i+j]=0;

d[i-j]=0;

e++;

}

}

}

 

voidmain()

{

intchoice,e=1;

charch;

printf("\n\n\t**WelcometoEightQueeninquiriessoftwareproblems**\n\n");

for(k=0;k<24;k++)//数据初始化

{

b[k]=0;

c[k]=0;

d[k]=0;

}

ch='y';

while(ch=='y'||ch=='Y')

{

printf("\n\t查询菜单\n");

printf("\n\t******************************************************");

printf("\n\t*No.1--------每一行皇后放置的列数的情况*");

printf("\n\t*No.2--------视图矩阵形式显示皇后的位置*");

printf("\n\t*No.0--------退出*");

printf("\n\t******************************************************");

printf("\n\t请选择菜单号(No.0--No.2):

");

scanf("%d",&choice);

switch(choice)

{

case1:

printf("\n\t每一行皇后放置的列数的情况\n\n");

PlaceQueen1

(1);//从第1个皇后开始放置

break;

case2:

printf("\n\t使用回车查看下一种情况\n\n");

PlaceQueen2

(1);//从第1个皇后开始放置

break;

case0:

ch='n';

break;

default:

printf("\n\t\t菜单选择错误,请重新输入!

\n");

}

}

}

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > IT计算机 > 计算机硬件及网络

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1