递归就是本次递归的方法内还需要继续执行递归;回溯就是因为本次的递归被终止或者return无参数时,上一次的递归方法需要继续往下执行那句----本次递归代码----接下来的代码操作
由于递归需要使用额外的栈空间,我们试着将递归转写为迭代。
开辟独立的栈空间相当于是入栈,而方法返回return相当于出栈(递归的运行机制的底层原理是栈!!!!)
案例一:迷宫回溯问题:(使用二维数组来模拟,递归算法)
八皇后问题:(回溯算法)
注意这个回溯算法的复杂度非常的高!!!
public class EightQueen {
int max=8;
int[] arr=new int[max];//8皇后的位置,这是个全局的变量(在递归时,也是共享的)
int count=0;//总的解法数
public static void main(String[] args) {
EightQueen e=new EightQueen();
e.check(0);
System.out.println(e.count);
}
//寻找皇后的放置位置
private void check(int n){
if(n==max){//说明打算放置第9个皇后
count++;
print();
return;//直接返回,不继续执行所在方法下面的操作了
// 具体解释回溯的特点:如果是在check(n-1)内就相当于出现了一个没有返回值的操作方法check(n)
}
for (int i = 0; i < max; i++) {//打算遍历每个列的位置来检索所有的组合情况
arr[n]=i;//数组存放的是每个皇后所在的列的位置
if(judge(n)){
//这个内部的两种可能:case1:继续回溯;case2:结束回溯,打印输出一种解法,此时会继续执行for循环去寻找新的解法
check(n+1);//如果当前的位置摆放没有冲突,我们继续拜访下一个皇后
}
//case0:如果当前的摆放位置不合适,则继续放置下一个位置
//case2:if中结束回溯,没有返回值,打印输出一种解法,此时会继续执行for循环去寻找新的解法
}
//说明第n个皇后没有合适的列的位置,我们需要回溯到上一个皇后的摆放位置来重新放置第(n-1)个皇后的位置
//这边隐形了一个return;
}
//查看当前放第n个皇后时,是否与前面的(n-1)个皇后位置冲突
private boolean judge(int n){
for (int i = 0; i < n; i++) {
//判断是否在一个列或者在一条对角线上
if(arr[i]==arr[n] || Math.abs(arr[i]-arr[n])==Math.abs(i-n)){
return false;
}
}
return true;
}
//最后将8皇后的位置输出
private void print(){
for (int i = 0; i <arr.length ; i++) {
System.out.print(arr[i]+" ");
}
System.out.println();
}
}
注意:静态方法不能引用全局变量,静态方法的静态特性,除非这个全局变量是个静态的