以前虽写过迷宫算法,但是非递归的,今天看数据结构,发现八皇后问题与迷宫问题很相似,八皇后、幕集输出、迷宫问题都可以用回溯法解决,即先序遍历求解过程当中的状态树。
以下是我写用回溯法解八皇后问题:其中 Box类省略了。
package cn.test;
import java.util.ArrayList;
import java.util.List;
/**
* 八皇后问题
* @author liubin
*
*/
public class Test {
//棋盘当前部局 的格子
public static int max=8;//矩阵行列数
public static void main(String[] args) {
List<Box> lst=new ArrayList<Box>();
trial(0,max,lst);
}
/**
* 递归方法
* @param row 当前行
* @param max 矩阵行列数
*/
public static void trial(int row ,int max,List<Box> lst){
if (row>=max){
//摆放完毕 输出图形
for(int p=0;p<lst.size();p++){
int x=lst.get(p).getRow();
int y=lst.get(p).getColumn();
switch(y){
case 0:System.out.println("*0000000");break;
case 1:System.out.println("0*000000");break;
case 2:System.out.println("00*00000");break;
case 3:System.out.println("000*0000");break;
case 4:System.out.println("0000*000");break;
case 5:System.out.println("00000*00");break;
case 6:System.out.println("000000*0");break;
case 7:System.out.println("0000000*");break;
}
}
System.out.println();
//return;
}else{
for(int j=0;j<max;j++){
//检测摆放是否合法
Box b=new Box();
b.setRow(row);
b.setColumn(j);
lst.add(b);
if(Legitimate(lst)){//布局合法
//System.out.println("合法");
trial(row+1,max,lst);
}else{//布局不合法移除
lst.remove(lst.size()-1);
}
//trial(row+1,max);
}//end else
lst.remove(lst.size()-1);
}//end else
}
/**
* 检测排列是否合法
* @param lst 要检测的棋子对列
* @return 是否合法 合法返回true 否则反回false
*/
public static boolean Legitimate(List<Box> lst){
//检测是否同行
//检测是否有同列
if (lst.size()==1)//队列只有一个元素
return true;
int x=lst.get(lst.size()-1).getRow();
int y=lst.get(lst.size()-1).getColumn();
for(int i=lst.size()-2;i>=0;i--){
int x1=lst.get(i).getRow();
int y1=lst.get(i).getColumn();
if(x==x1||y==y1){
//System.out.println("同行或同列");
return false;
}
if ( Math.abs( ((float)(y1-y))/(x1-x) )==1 ){//在同一对角线上
//System.out.println("在同一对角线上");
return false;
}
}
return true;
}
}
运行结果:
*0000000
0000*000
0000000*
00000*00
00*00000
000000*0
0*000000
000*0000
以下是幕集输出程序:
package cn.test;
/**
* 幕集输出程序
*/
import java.util.ArrayList;
import java.util.List;
public class Test {
public static int var[]={1,2,3};
public static int k=0;//var 初始序列
/**
* 主函数
* @param args
*/
public static void main(String[] args) {
List lst=new ArrayList<Integer>();
PowerSet(var,lst,k);
}
/**
* 递归函数
* @param sa 原始集合
* @param sb 原始集合的幕集
* @param k
*/
public static void PowerSet(int sa[],List<Integer> sb,int k){
if(k>sa.length-1){
//输出幕集
for(int j=0;j<sb.size();j++){
System.out.print(sb.get(j)+" ");
}
System.out.println();
}else{
//取一个原始集合元素
sb.add(sa[k++]);
PowerSet(sa,sb,k);
//舍一个原始集合元素
sb.remove(sb.size()-1);
PowerSet(sa,sb,k);
}//end else
}
}
运行结果:
1 2 3
1 2
1 3
1
2 3
2
3