数据结构--递归

1.递归应用场景

实际应用场景,迷宫问题(回溯)、八皇后问题、快速排序、 递归(Recursion)

2.递归的概念

简单的说: 递归就是方法自己调用自己,每次调用时传入不同的变量.递归有助于编程者解决复杂的问题,同时可以让代码变得简洁。

3.递归需要遵守的重要规则

1) 执行一个方法时,就创建一个新的受保护的独立空间(栈空间)

2) 方法的局部变量是独立的,不会相互影响, 比如 n 变量

3) 如果方法中使用的是引用类型变量(比如数组),就会共享该引用类型的数据.

4) 递归必须向退出递归的条件逼近,否则就是无限递归,出现 StackOverflowError,死归了:)

5) 当一个方法执行完毕,或者遇到 return,就会返回,遵守谁调用,就将结果返回给谁,同时当方法执行完毕或者返回时,该方法也就执行完毕

4. 递归-迷宫问题

 1 package mainProject;
 2 //1:代表墙  2:代表可通行路径  3:代表阻塞路径
 3 
 4 //迷宫算法
 5 public class MiGongDemo {
 6     public static void main(String[] args) {
 7         int[][] map = new int[8][7];
 8         getMap(map);
 9         setWay(map,1,1);
10         System.out.println("——————————————————————————————————");
11         getMap(map);
12     }
13 
14     //地图绘制
15     public static void getMap(int[][] map){
16 
17 
18         for(int i=0;i<7;i++){
19             map[0][i] = 1;
20             map[7][i] = 1;
21         }
22         for(int i=0;i<8;i++){
23             map[i][0] = 1;
24             map[i][6] = 1;
25         }
26         map[3][1] = 1;
27         map[3][2] = 1;
28         map[4][3] = 1;
29         for(int i =0;i<8;i++){
30             for(int j = 0;j<7;j++){
31                 System.out.print(map[i][j]+" ");
32             }
33             System.out.println();
34         }
35     }
36     /**
37      * 寻路方法
38      * @param map:地图
39      * @param i:位置i坐标
40      * @param j:位置j坐标
41      * 执行策略:上右上左
42      */
43     public static boolean setWay(int[][] map,int i,int j){
44         if(map[6][5] == 2){
45             //找到目标位置了
46             return true;
47         }else {
48             if(map[i][j] == 0){
49                 map[i][j] = 2;
50                 if(setWay(map,i+1,j)){
51                     return true;
52                 }else if(setWay(map,i,j+1)){
53                     return true;
54                 }else if(setWay(map,i-1,j)){
55                     return true;
56                 }else if(setWay(map,i,j-1)){
57                     return true;
58                 }else {
59                     map[i][j] = 3;
60                     return false;
61                 }
62             }else {
63                return false;
64             }
65         }
66     }
67 
68 }

结果

1 1 1 1 1 1 1 
1 0 0 0 0 0 1 
1 0 0 0 0 0 1 
1 1 1 0 0 0 1 
1 0 0 1 0 0 1 
1 0 0 0 0 0 1 
1 0 0 0 0 0 1 
1 1 1 1 1 1 1 
——————————————————————————————————
1 1 1 1 1 1 1 
1 2 0 0 0 0 1 
1 2 2 2 0 0 1 
1 1 1 2 2 0 1 
1 0 0 1 2 0 1 
1 0 0 0 2 0 1 
1 0 0 0 2 2 1 
1 1 1 1 1 1 1 

5.八皇后问题

思路分析:

1) 第一个皇后先放第一行第一列

2) 第二个皇后放在第二行第一列、然后判断是否 OK, 如果不 OK,继续放在第二列、第三列、依次把所有列都放完,找到一个合适

3) 继续第三个皇后,还是第一列、第二列……直到第 8 个皇后也能放在一个不冲突的位置,算是找到了一个正确解

4) 当得到一个正确解时,在栈回退到上一个栈时,就会开始回溯,即将第一个皇后,放到第一列的所有正确解, 全部得到.

5) 然后回头继续第一个皇后放第二列,后面继续循环执行 1,2,3,4 的步骤

 1 package mainProject;
 2 
 3 
 4 //八皇后问题
 5 public class QueueDemo {
 6     //八个皇后 表示共有多少个皇后
 7     private static int maxSize = 4;
 8     //定义数组 array, 保存皇后放置位置的结果,比如 arr = {0 , 4, 7, 5, 2, 6, 1, 3}
 9     //下标1 value0:第一行 第1个位置;下标2 value4:第二行 第5个位置
10     private static int[] array = new int[maxSize];
11     private static int count = 0;
12 
13     public static void main(String[] args) {
14         check(0);
15         System.out.println(count);
16     }
17 
18 
19     //打印输出结果
20     public static void printQueue(){
21         count++;
22         for(int i = 0;i<array.length;i++){
23             System.out.print(array[i]+" ");
24         }
25         System.out.println();
26     }
27 
28     /**
29      * //判断前后皇后是否冲突
30      * @param n :第n个皇后
31      */
32     public static boolean judge(int n){
33         for(int i = 0;i<n;i++){
34             //1. array[i] == array[n]    表示判断 第 n 个皇后是否和前面的 n-1 个皇后在同一列(array【x】 ==>表示位置,i/n表示第几个皇后)
35             //2. Math.abs(n-i) == Math.abs(array[n] - array[i]) 表示判断第 n 个皇后是否和第 i 皇后是否在同一斜线
36             if(array[i]==array[n] || Math.abs(n-i) == Math.abs(array[n]-array[i])){
37                 return false;
38             }
39         }
40         return true;
41     }
42 
43     //放置第n个皇后
44     //特别注意: check 是 每一次递归时,进入到 check 中都有    for(int i = 0; i < max; i++),因此会有回溯
45     public static void check(int n){
46         //如果皇后数等于最大拟定数,那么完成放置
47         if(n == maxSize){
48             printQueue();
49             return;
50         }
51         //依次放入皇后,并判断是否冲突
52         for(int i = 0;i < maxSize;i++){
53             //先把当前这个皇后 n 的位置, 放到该行的第 i 列
54             //array【x】 ==>表示位置
55             array[n] = i;
56             if(judge(n)){
57                 //不冲突 接着放 n+1 个皇后,即开始递归
58                 check(n+1);
59             }
60             //如果冲突,就继续执行 array[n] = i; 即将第 n 个皇后,放置在本行得 后移的一个位置
61         }
62     }
63 }

 

posted @ 2022-05-08 18:52  jason饼干大怪兽  阅读(48)  评论(0)    收藏  举报