递归思想
递归
简单来讲就是自己调用自己,每次传入不同的变量,递归有助于编程者解决复杂的问题,同时让代码
变得比较简洁
递归可以使用在很多地方,比如快速排序,归并排序等等
打印输出问题
public static void test(int n){
if (n>2){
test(n-1);
}
System.out.println("n="+n);
}
阶乘问题
public static int test2(int n){
if (n==1){
return n;
}else {
return n*test2(n-1);
}
}
递归需要遵守的重要规则
1.执行一个方法时,就会产生一个独立的空间(栈空间)
2.方法的局部变量是独立的,不会相互影响,不如n变量
(如果方法中使用的是引用类型的变量,就会共享该引用类型的数据比如数组)
3.递归必须向递归的条件逼近,否则就是死递归,发生栈溢出
5.当一个方法执行完毕后,或者遇到return,就会返回,遵守谁调用,就将结果返回给谁,同时当
方法执行完毕或者返回是,该方法就执行完毕
迷宫问题
//使用递归回溯给小球找路
//1.i,j是从那个位置开始找
//2.如果找到通路就返回true,找不到就返回false
//3.如果小球能到map[6][5],说明通路找到
//4.当map[i][j]为0时,表示该点还没有走过,当为2时候表示是通路还没有走,3表示该点已经
走过,但是走不通
//5.我们在走迷宫时候必须有一个策略,比如 下-》右-》上-》左
代码实现
public static boolean setWay(int[][] map,int i,int j){
if (map[6][5]==2){//说明通路已经找到
return true;
}else{
//先看这条路走没走过
if (map[i][j]==0){//如果当前点没有走过
//按照策略走 下-》右-》上-》左
map[i][j]=2;//假定该点可以走通
if (setWay(map,i+1,j)){//向下走
return true;
}else if (setWay(map,i,j+1)){//向右走
return true;
}else if (setWay(map,i-1,j)){//向上走
return true;
}else if (setWay(map,i,j-1)){//向左走
return true;
}else{
//说明该点走不通,是死路
map[i][j]=3;
return false;
}
}else {
//如果map[i][j]!=0,可能是1,2,3
return false;
}
}
}
迷宫问题的得到的路径和我们的策略有关,怎样找出最短路径?
将走过的所有路拿出来,2最少的地图就是最短路径
八皇后问题
在8*8格的国际象棋上摆放八个皇后,是其不能互相攻击,即:任意两个皇后都不能处于同一行,同
一列或同一斜线上,问有多少种摆法
思路分析
1.将第一个皇后放在第一行第一列
2.将第二个皇后放在第二行第一列。然后判断是否ok,如果不ok就继续放在第二列,第三列,一次将
所有的列都放完,找到一个合适的
3.继续将第三个皇后还是像第二行的皇后一样
4.当的到一个正确的解时,在栈回退到上一个栈时,就会开始回溯,即将第一个皇后,放在第一列所
有的正确解,全部都得到
5.然后回头继续将第一个皇后放第二列,后面继续循环1,2,3,4的步骤
说明:理论上应该创建一个二位数组来表示棋盘,但是实际上可以通过算法,用一个一维数组即可解
决问题,arr[8]={0,4,7,5,2,6,1,3}下标对应的是行,元素对应的是列;arr[i]=val,表示第i+1
行,第val+1列
代码实现
public class Queue8 {
//定义一个max表示共有多少个皇后
static int max=8;
//定义一个数组,保存皇后放置位置的结果,比如 arr[8]={0,4,7,5,2,6,1,3}
static int[] array=new int[8];
static int count=0;
public static void main(String[] args) {
check(0);
System.out.println("一共有"+count+"种解法");
}
//编写一个方法放置第n个皇后
private static void check(int n){
if (n==max){//n==8 ,其实八个皇后已经放好了
count++;
print();
return;
}
//依次放入皇后,并判断是否冲突
for (int i=0;i<max;i++){
//先把当前这个皇后n放到该行的第一列
array[n]=i;
//判断当第n个皇后放i列时,是否冲突
if (judge(n)){//说明不冲突
//接着放第n+1个皇后,开始递归
check(n+1);
}
//如果冲突就继续执行array[n]=i;即将第n个皇后防止在本行的后移的一个位置
}
}
//查看当我们放置第n个皇后,就去检测该皇后是否和前面已经摆放的皇后冲突
//n表示第n个皇后
private static boolean judge(int n){
for (int i=0;i<n;i++){
//1.array[i]==array[n] 表示判断第n个皇后是否和第i个皇后在同一列
/*2.Math.abs(n-i)== Math.abs(array[n]-array[i] 表示判断第n个皇后是否和第i个
皇后在同一斜线,可以放在坐标系中理解*/
//3.判断是否在同一行,没有必要判断,因为n每一次都在递增,所以不可能在同一行
if (array[i]==array[n] || Math.abs(n-i)== Math.abs(array[n]-array[i])){
return false;
}
}
return true;
}
//写一个方法,可以将皇后摆放的位置打印出来
private static void print(){
for (int value : array) {
System.out.print(value + " ");
}
System.out.println();
}
}

浙公网安备 33010602011771号