回溯N皇后问题-循环解决

循环代码稍微复杂一点,不过再大的棋盘都不会有内存溢出问题。

15皇后存在序列太多,粘贴了最后几组,期盘大小为15时,共2279184个摆法。

2279177 : 14 12 10 8 1 5 13 2 0 7 11 4 6 9 3 
2279178 : 14 12 10 8 2 11 1 3 0 6 9 13 5 7 4 
2279179 : 14 12 10 8 3 1 4 11 9 0 13 5 7 2 6 
2279180 : 14 12 10 8 3 1 9 2 0 11 7 5 13 6 4 
2279181 : 14 12 10 8 3 5 0 2 9 11 13 7 4 6 1 
2279182 : 14 12 10 8 3 5 0 11 1 6 13 9 7 4 2 
2279183 : 14 12 10 8 6 1 3 13 0 7 9 11 5 2 4 
2279184 : 14 12 10 13 5 3 1 11 2 6 9 0 8 4 7 


以下为主要代码.

package ls.algorithm.queen;



public class NQueenT implements NQueenInf {


static final int size=15;
int[] pos=new int[size];
int currentR=0,currentC=0;
int number=0;
@Override
public void start() {
// TODO Auto-generated method stub
while(currentR>=0)
{
switch(isPosValid())
{
//该坐标不符合要求,且无后续可搜索坐标
case -1:
pos[currentR]=0;
currentR--;//需要回溯到上一行
//这里如果不加条件,当回溯到-1行时,这里还没跳出循环会造成数组越界异常。
if(currentR>=0)
{
currentC=pos[currentR]+1;//验证上一行的后面一个列坐标,继续搜索是否有符合的序列
}
break;
//该坐标不符合要求,但该列后面还有坐标为验证,可继续往后搜索
case 0:
pos[currentR]=0;
currentC++;//继续搜索下一个坐标
break;
case 1:
//该坐标符合要求,序列还未找全。
pos[currentR]=currentC;//记录上一行有效列位置
currentR++;//跳到下一行
currentC=0;//从该行第0开始搜索符合的坐标
break;
case 2:
//该坐标符合要求,且是最后一行的序列。
pos[currentR]=currentC;//记录该行有效列位置
printPosition();//打印当前记录的N皇后序列
pos[currentR]=0;//重置最后一个序列记录
currentC++;//继续验证该行下一个坐标
break;
}
}
System.out.print("搜索结束");
}



//-1代表不成功且这是该列已经是这一行的最后一列了
//0代表不成功但该行后面还有未验证的列
//1代表成功但不是最后一行,
//2代表成功,而且是最后一行
private int isPosValid()
{
//超出棋盘的列大小,说明这一行没有找到合适的序列,需要进行回溯
if(currentC>size-1)
{
return -1;
}
for(int n=0;n<currentR;n++)
{
if((pos[n]==currentC)||
(Math.abs(currentC -pos [n])==Math.abs(currentR-n))
)
{
//该坐标不符合要求,继续查找下一列
return 0;
}
}
//该坐标符合验证要求
if(currentR ==size-1)
{
//最后一行,表示已经有符合的位置序列
//继续查找下一列
return 2;
}
else if(currentR<size-1)
{
//不是最后一行,需要继续验证后面行的序列
//跳到下一行
return 1 ;
}
else
{
System.out.print("出现异常,这一句理论上不应该被访问到!");
return 2;
}
}


//打印当前符合序列的棋盘
void printPosition()
{
number++;
System.out.print(number+" : ");
for(int n=0;n<size ; n++)
{
System.out.print(pos[n]+" ");
}
System.out.print("\n");
}


}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值