借鉴:1、http://blog.csdn.net/baple/article/details/7181404
2、http://www.cnblogs.com/steven_oyj/archive/2010/05/22/1741376.html 回溯之模板
3、《大话数据结构》 P240页,深度优先遍历的概念(类似于树的前序遍历)
4、这里有个对比,非递归比递归法更能体现出回溯的过程!
回溯题目解题一般步骤:1、找到题解的空间 2、找到约束条件 3、找到扩展的规则(下一步怎么走)
回溯之非递归算法:
package database;
public class NQuee2 {
public static void NQuee2(int arr[],int n){
int k=1 ;
arr[1]=0; // 首先对进行初始化!(确定第一步先放在哪)
while(k>0){
arr[k]=arr[k]+1;
while(arr[k]<=n && !Verify(arr,k))
arr[k] = arr[k]+1;
if(arr[k]<=n){ //这里能够看出什么时候回溯!
if(k==n)
ResultPrint(arr,n);
else{
k=k+1;
arr[k]=0;
}
}else k=k-1;
}
}
public static boolean Verify(int arr[],int i){ //仅仅判断能不能放置这个皇后
for(int k =1;k != i;k++) //与前i-1行进行比较
if(Math.abs(k-i)==Math.abs(arr[i]-arr[k]) || arr[i] == arr[k]) //具体比较的方法;
return false;
return true;
}
public static void ResultPrint(int arr[],int n){
for(int a =1 ;a!=n+1 ;a++)
System.out.print(a+","+arr[a]+";");
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int n = 4;
int arr[] = new int[n+1]; //为什么是n+1? 这里要用n+1个空间,因为多一个空间是为了判断解是否超越了解空间!(a[k]>n的情况)
//如果超过了就回溯,如果没超过而且满足条件就继续往下
NQuee2(arr,n);
}
}
回溯之递归算法:
package database;
public class NQuee {
public static boolean Verify(int arr[],int i){ //仅仅判断这个位置(int arr[],int i)能不能放置这个皇后
for(int k =1;k != i;k++) //与前i-1行进行比较
if(Math.abs(k-i)==Math.abs(arr[i]-arr[k]) || arr[i] == arr[k]) //具体比较的方法;
return false;
return true;
}
public static void NQuee(int arr[] , int i , int n){
for(int j = 1;j!=n+1;j++){ //这里是尝试着往 第i行添加皇后
arr[i] = j; //尝试着往(i,arr[i])添加皇后
//这里注意:arr[i],而i是从1开始的,那么说arr[]要开辟n+1个空间
if(Verify(arr, i)){ //利用递归开始进行回溯算法
if(i == n) //考虑是如何进行回溯的?见PPT
ResultPrint(arr,n);
else
NQuee(arr, i+1, n);
}
}
}
public static void ResultPrint(int arr[],int n){
for(int a =1 ;a!=n+1 ;a++)
System.out.print(a+","+arr[a]+";");
}
public static void main(String[] args) {
int n = 4;
int arr[] = new int[n+1]; //为什么是n+1? 这里要用n+1个空间,因为多一个空间是为了判断解是否超越了解空间!(a[k]>n的情况)
//如果超过了就回溯,如果没超过而且满足条件就继续往下
//数组初始化为0
NQuee(arr,1,n);
}
}
后记:回溯法之模板
1、非递归
int a[n],i;
初始化数组a[ ];
i=1;
While (i>0(有路可走)) and (未达到目标) //还未回溯到头
{ if (i=n) 搜索到一个解,输出; //搜索到叶结点
else //正在处理第i个元素
{a[i]第一个可能的值;
while (a[i]不满足约束条件且在搜索空间内)
a[i]下一个可能的值;
if (a[i]在搜索空间内)
{标识占用的资源; i=i+1;} //扩展下一个结点
else {清理所占的状态空间;i=i-1;} //回溯
}
}
递归框架:
int a[n];
try(int i)
{ if (i>n) 输出结果;
else
for(j=下界 ;
j<=上界;
j++)
//枚举i所有可能的路径
{
if ( check(j)=1) //满足限界函数和约束条件
{ a[i]=j;
…… //其它操作
try(i+ 1);}
回溯前的清理工作(如:a[i]置空值); //有的要重头开始排序!
}
}