1、八皇后问题 回溯 非递归的 java实现,注释写得详细了,最好还是自己先写写:
import java.util.Scanner;
public class Queen {
private static int count=0;
private static boolean isExist=false;
public static void main(String []args) {
int n;
Scanner in=new Scanner(System.in);
System.out.println("请输入皇后数目:");
n=in.nextInt();
int [][] flag=new int[n][n];
int [][] record=new int[2][n];
reset(flag);
reset(record);
parseQueen(flag,record);
if(!isExist)
System.out.println(n+"皇后不存在路径");
else
System.out.println(n+"皇后有"+count+"条路径");
in.close();
}
private static void reset(int[][] flag) {
int i,j,m=flag.length,n=flag[0].length;
for( i=0;i<m;i++)
for(j=0;j<n;j++){
flag[i][j]=-1;
}
}
private static void parseQueen( int[][] flag,int[][] record) {
int i=0,j=0,len=flag.length;
//System.out.println("length="+len);
while(true){
if(record[1][i]!=-1){//判断当前点是否为上次退行的位置,是则进行再定位
//清除原来在回溯一行定位的点
j=record[1][i];
record[1][i]=-1;
flag[i][j]=-1;
if(j<len-1) j++;//往右移
else{
if(i>0) i--;//往上移
else return ;//结束
}
}
else{//当前点为普通点
// System.out.println(i+" "+j+" "+isTrue(record,i,j));
if(!isTrue(record,i,j)){//该定位点位置不满足要求
if(j<len-1) j++;//往右找定位点
else{
if(i>0) i--;//往上找定位点
else return ;//结束
}
}
else{//该定位点位置满足要求
//放置定位点
flag[i][j]=1;
record[0][i]=i;
record[1][i]=j;
if(i<len-1){//往下走
i++;
j=0;
}
else{//到末尾,找到一条路径
isExist=true;
printArray(flag);//打印
record[1][i]=-1;//做回溯处理准备
flag[i][j]=-1;
if(i==0)//结束
return ;
i--;//往上继续搜寻
}
}
}
}
}
private static void printArray(int[][] flag) {
int i,j,len=flag.length,len2=flag[0].length;
count++;
System.out.println("这是第"+count+"路径:");
for( i=0;i<len;i++){
for(j=0;j<len2;j++){
if(flag[i][j]==-1)
System.out.print("0 ");
else
System.out.print("1 ");
}
System.out.println();
}
System.out.println();
//reset(flag);
}
private static void show(int[][] flag) {
int i,j,len=flag.length,len2=flag[0].length;
for( i=0;i<len;i++){
for(j=0;j<len2;j++)
System.out.print(flag[i][j]+" ");
System.out.println();
}
System.out.println();
}
private static boolean isTrue(int[][] record, int m, int n) {
int left = n-1,right = n+1,len=record[0].length;
boolean f=true;
if(m==0)
return true;
else{
for(int i=m;i>0;){
i--;
// System.out.println("是否越边界 "+m+" "+n+" "+i+" "+record[1][i]+" "+right);
if(record[1][i]==n){//是否同一列
f=false;
break;
}
if(left>=0){
if(record[1][i]==left){//是否同一右斜
f=false;
break;
}
else
left--;
}
if(right<=len-1){
if(record[1][i]==right){//是否同一左斜
f=false;
break;
}
else
right++;
}
}
}
return f;
}
}