您的位置:首页 > 理论基础 > 数据结构算法

数据结构之回溯算法

2016-02-20 22:17 387 查看
借鉴: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
,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
;

try(int i)

{ if (i>n) 输出结果;

else

for(j=下界 ;
j<=上界;
j++)
//枚举i所有可能的路径

{
if ( check(j)=1) //满足限界函数和约束条件

{
a[i]=j;

…… //其它操作

try(i+ 1);}

回溯前的清理工作(如:a[i]置空值); //有的要重头开始排序!

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: