数据结构课程设计之八皇后问题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
注意:本文编程使用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() //递归寻找摆放皇后位子
void main() //主函数调用
2.3 算法流程
1.数据初始化。
2.从n列开始摆放第n个皇后(因为这样便可以符合每一竖列一个皇后的要求),先测试当前位置(n,m)是否等于0(未被占领)。如果是,摆放第n个皇后,并宣布占领(记得姚横列竖列斜列一起设置),接着进行递归;如果不是,测试下一个位置(n,m+1),但是如果当n<=8,m=8时,发现此时已无法摆放时,便要进行回溯。从问题的某一种可能出发,搜索从这种情况能出发,继续搜索,这种不断“回溯”的寻找解的方法,称为“回溯法”。
3. 当n>8时,便打印出结果。
其算法流程图如下:
三、详细设计
//定义数组
int a[8] //表示第i个皇后放置的列,范围为1~8。
int b[8] //表示第j行空闲,b[j]=1 表示第j行被占领,范围为1~8 int c[30] //表示第(i-j)条对角线空闲,c[i-j]=1 表示第(i-j)条对角线被占领,范围-7~7
int d[30] //表示第(i+j)条对角线空闲,d[i+j]=1 表示第(i+j)条对角线被占领,范围2~16。
//位置标明法打印
void print1()
{
X++;
cout<<"\tNo."< for (k=1;k<9;k++)