八皇后问题是数据结构的基础问题,解决的是在一个8*8的棋盘上放8个国际象棋中的皇后,并保证8个皇后不能被其他皇后吃掉。根据国际象棋的规则,皇后可以吃同一列、同一行或同一列的棋子。
回搠是数据结构的基本思想,当一个问题遇到一个岔路口,不知道哪条路正确时,我们可以试着走其中一条路,如果这条路不能走,就回到原来的岔路口试另一条路。
在解决八皇后这个特定问题时,我们可以一行一行放入皇后。需要注意的地方是,我们看待棋盘的视角是8*8的格子,而皇后看待棋盘的视角是行,列和对角线,所以如果把棋盘看成8行、8列、15个左对角线和15个右对角线会方便一些。
八皇后问题非常典型,以至于可以成为大家公认的计量工作量的单位。比如在敏捷开发中,编写一个程序解决八皇后问题可以成为sprint计划会议上的一个故事点,以此为基础大家估计其他故事需要的故事点数。
Java实现的八皇后代码:
/**
* @author cuiods
*/
public class EightQueue {
private int size;
private int[] position;
private boolean[] columnAvailable;
private boolean[] leftDialogAvailable;
private boolean[] rightDialogAvailable;
public EightQueue(int size) {
assert size > 3;
this.size = size;
position = new int[size];
columnAvailable = new boolean[size];
leftDialogAvailable = new boolean[size * 2 - 1];
rightDialogAvailable = new boolean[size * 2 - 1];
for (int i = 0; i < size; i++) {
position[i] = -1;
columnAvailable[i] = true;
}
for (int i = 0; i < 2*size-1; i++) {
leftDialogAvailable[i] = true;
rightDialogAvailable[i] = true;
}
}
public void putQueue() {
putQueue(0);
}
private void putQueue(int row) {
for (int col = 0; col < size; col++) {
if (columnAvailable[col] && leftDialogAvailable[col+row] && rightDialogAvailable[row-col+size-1]) {
position[row] = col;
columnAvailable[col] = false;
leftDialogAvailable[col+row] = false;
rightDialogAvailable[row-col+size-1] = false;
if (row != size-1) {
putQueue(row+1);
} else {
printChessBoard();
}
position[row] = -1;
columnAvailable[col] = true;
leftDialogAvailable[col+row] = true;
rightDialogAvailable[row-col+size-1] = true;
}
}
}
private void printChessBoard() {
System.out.println("-----------------------------");
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
if (position[i]==j)
System.out.print("x ");
else
System.out.print(". ");
}
System.out.println();
}
}
}
运行截图: