一、递归

1. 代码示例:

  1. public class RecursionTest {
  2. public static void main(String[] args) {
  3. test(10);
  4. }
  5. // 递归方法
  6. public static void test(int n){
  7. if(n>2){
  8. test(n-1);
  9. }
  10. System.out.println("n="+n);
  11. }
  12. }

2. 执行结果

image.png

3. 逻辑讲解:

image.png
解析:
当n=4时,会在test(3)处重新创建一个栈
当n=3时,会在test(2)处重新创建一个栈
当n=2时,在判断n>2之后,执行打印程序;
执行完打印程序后,当前的n=2的栈弹出;执行n=3时的栈。此时再执行打印程序;
依此类推;

4. 递归能解决的问题

image.png

5. 实际运用—-迷宫问题

  1. package com.atguigu.Recursion;
  2. public class MiGongDemo {
  3. public static void main(String[] args) {
  4. // 先创建二维数组模拟迷宫,八行七列
  5. // 地图
  6. int[][] map = new int[8][7];
  7. // 使用1表示墙,先把上下置为1
  8. for (int i = 0; i < 7; i++) {
  9. map[0][i] = 1;
  10. map[7][i] = 1;
  11. }
  12. // 左右也置为1
  13. for (int j = 0; j < 8; j++) {
  14. map[j][0] = 1;
  15. map[j][7] = 1;
  16. }
  17. // 设置挡板
  18. map[3][1] = 1;
  19. map[3][2] = 1;
  20. }
  21. // 使用递归给小球找路
  22. /**
  23. * localMap: 输入地图
  24. * int i,int j: 起始位置
  25. * 约定: 当map[i][j]=0时表示该点还没走过,当为1时,表示是墙,不能走,当为3时,思路走不通
  26. * 在走迷宫时,需要确定一个策略(方法):下-->左-->上-->右,如果该点走不通再回溯
  27. */
  28. public static boolean findWay(int[][] localMap,int i,int j){
  29. if(localMap[6][5]==2){
  30. return true;
  31. }else{
  32. if(localMap[i][j]==0){
  33. // 当前点还没走过
  34. localMap[i][j]=2; // 先假定该点是可以走通的,如果走不通,则回溯
  35. // 下-->左-->上-->右
  36. if(findWay(localMap,i+1,j)){
  37. return true;
  38. }else if(findWay(localMap,i,j+1)){
  39. return true;
  40. }else if(findWay(localMap,i-1,j)){
  41. return true;
  42. }else if(findWay(localMap,i-1,j-1)){
  43. return true;
  44. }else{
  45. localMap[i][j]=3;
  46. return false;
  47. }
  48. }else { // 当不是0时,表明已经走过不能在走,或者时墙走不通
  49. return false;
  50. }
  51. }
  52. }
  53. }

6. 八皇后问题

  1. Math.abs(n-i)==Math.abs(resArray[n]-resArray[i]) 判断第n个皇后是否和第i个皇后在同一斜线。按照正方向来计算,对角线置为的长和高相等
  1. resArray[i]==resArray[n] 判读第n个是否和前面所有的皇后在同一列
  1. package com.atguigu.Recursion;
  2. import java.util.Arrays;
  3. public class Queue8Demo {
  4. // 定义一个max表示有多少个皇后
  5. int max = 8;
  6. // 定义一个数组,保存位置的结果
  7. int[] resArray= new int[];
  8. public static void main(String[] args) {
  9. }
  10. // 编写一个方法,放置第n个皇后
  11. private void check(int n){
  12. if(n==max){ // 放第9个皇后,不需要
  13. print();
  14. return;
  15. }
  16. // 依次放入皇后,并判断是否冲突
  17. for (int i = 0; i < max; i++) {
  18. // 先把当前皇后放到该行的第1列
  19. resArray[n]=i;
  20. // 判断第n个皇后到i列时,是否冲突
  21. if(isConflict(n)){
  22. //如果不冲突,放第n+1个皇后
  23. check(n+1);
  24. }
  25. // 如果冲突,就执行i++,即移动当前皇后到后一个位置
  26. }
  27. }
  28. // 查看当我们放置第N个皇后,就去检测该皇后是否和之前已摆放的皇后冲突
  29. private boolean isConflict(int n){
  30. for (int i = 0; i < n; i++) {
  31. // 1. resArray[i]==resArray[n] 判读第n个是否和前面所有的皇后在同一列
  32. // 2. Math.abs(n-i)==Math.abs(resArray[n]-resArray[i]) 判断第n个皇后是否和第i个皇后在同一斜线。按照正方向来计算,对角线置为的长和高相等
  33. if(resArray[i]==resArray[n]||Math.abs(n-i)==Math.abs(resArray[n]-resArray[i])){
  34. return false;
  35. }
  36. }
  37. return true;
  38. }
  39. // 写一个方法可以把结果打印出来
  40. private void print() {
  41. for (int i = 0; i < resArray.length; i++) {
  42. System.out.printf("第%d行摆放的皇后位置是:%d \n",i,resArray[i]);
  43. }
  44. }
  45. }