Java编程内功-数据结构与算法「递归」

开发 后端 算法
递归就是方法自己调用自己,每次调用时传入不同的变量.递归有助于编程者解决复杂的问题,同时可以让代码变得整洁.

[[392763]]

概念

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

递归能解决什么样的问题

  1. 各种数学问题如:八皇后问题,汉诺塔,阶乘问题,迷宫问题,球和篮子问题(google编程大赛).
  2. 各种算法中也会用到递归,比如快排,归并排序,二分查找,分治算法等.
  3. 将用栈解决的问题->递归代码比较简洁.

递归需要遵守的规则

  1. 执行一个方法时,就创建一个新的受保护的独立空间(栈空间).
  2. 方法的局部变量是独立的,不会相互影响.
  3. 如果方法中使用的变量是引用类型的变量(比如数组),就会共享该引用类型的数据.
  4. 递归必须向退出递归的条件逼近,否则就是无限递归.
  5. 当一个方法执行完毕,或者遇到return,就会返回,遵守谁调用就将结果返回给谁,同时当方法执行完毕或者返回时,该方法也就执行完毕.

递归回溯解决迷宫问题

在一个二维数组中,1表示墙,求小球从指定点到终点走过的路径.

  1. package com.structures.recursion; 
  2.  
  3. public class MiGong { 
  4.     public static void main(String[] args) { 
  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.         for (int i = 0; i < 8; i++) { 
  13.             map[i][0] = 1; 
  14.             map[i][6] = 1; 
  15.         } 
  16.         //设置挡板 
  17.         map[3][1] = 1; 
  18.         map[3][2] = 1; 
  19.         //输出地图 
  20.         System.out.println("原始地图"); 
  21.         for (int i = 0; i < 8; i++) { 
  22.             for (int j = 0; j < 7; j++) { 
  23.                 System.out.print(map[i][j] + " "); 
  24.             } 
  25.             System.out.println(); 
  26.         } 
  27.  
  28.         //使用递归回溯找路 
  29.         setWay(map, 1, 1); 
  30.         System.out.println("按策略走过的路"); 
  31.         for (int i = 0; i < 8; i++) { 
  32.             for (int j = 0; j < 7; j++) { 
  33.                 System.out.print(map[i][j] + " "); 
  34.             } 
  35.             System.out.println(); 
  36.         } 
  37.  
  38.         /* 
  39.         原始地图 
  40.         1 1 1 1 1 1 1 
  41.         1 0 0 0 0 0 1 
  42.         1 0 0 0 0 0 1 
  43.         1 1 1 0 0 0 1 
  44.         1 0 0 0 0 0 1 
  45.         1 0 0 0 0 0 1 
  46.         1 0 0 0 0 0 1 
  47.         1 1 1 1 1 1 1 
  48.         按策略走过的路 
  49.         1 1 1 1 1 1 1 
  50.         1 2 0 0 0 0 1 
  51.         1 2 2 2 0 0 1 
  52.         1 1 1 2 0 0 1 
  53.         1 0 0 2 0 0 1 
  54.         1 0 0 2 0 0 1 
  55.         1 0 0 2 2 2 1 
  56.         1 1 1 1 1 1 1 
  57.          */ 
  58.     } 
  59.  
  60.     /** 
  61.      * 使用递归回溯来找路,如果能map[6][5]位置,则说明通路找到 
  62.      * 约定:当map[i][j]为0表示该点没有走过,当为1表示墙,当为2表示通路可以走,3表示该点已经走过,但是走不通 
  63.      * 在走迷宫时,需要确定一个策略(方法),下->右->上->左,如果走不通再回溯 
  64.      * 
  65.      * @param map 表示地图 
  66.      * @param i   从哪个位置开始行坐标 
  67.      * @param j   从哪个位置开始列坐标 
  68.      * @return 如果找到通路, 就返回true, 否则返回false 
  69.      */ 
  70.     public static boolean setWay(int[][] map, int i, int j) { 
  71.         if (map[6][5] == 2) { 
  72.             return true
  73.         } else { 
  74.             if (map[i][j] == 0) {//如果当前这个点没有走过 
  75.                 //按照策略下->右->上->左 走 
  76.                 map[i][j] = 2;//假定该点可以走通 
  77.                 if (setWay(map, i + 1, j)) {//向下走 
  78.                     return true
  79.                 } else if (setWay(map, i, j + 1)) {//向右走 
  80.                     return true
  81.                 } else if (setWay(map, i - 1, j)) {//向上走 
  82.                     return true
  83.                 } else if (setWay(map, i, j - 1)) {//向左走 
  84.                     return true
  85.                 } else { 
  86.                     map[i][j] = 3;//说明该点是死路,走不通 
  87.                     return false
  88.                 } 
  89.             } else { 
  90.                 //如果map[i][j] != 0,说明可能是1,2,3 
  91.                 return false
  92.             } 
  93.         } 
  94.     } 

八皇后问题

在8*8的国际象棋上摆放8个皇后,使其不能相互攻击,即:任意两个皇后都不能处于同一行,同一列,同一斜线上,问有多少种摆法.

理论上应该创建一个二维数组来表示棋盘,但是实际上可以通过算法,用一个一维数组即可解决问题,arr[8]={0,4,7,5,2,6,1,3},对应arr下标表示第几行,即第几个皇后,arr[i]=val,val表示第i+1个皇后,放在第i+i行的val+1列.

  1. package com.structures.recursion; 
  2.  
  3. public class Queen8 { 
  4.     //表示共有多少个皇后 
  5.     private int max = 8; 
  6.     //定义数组array,保存皇后放置位置的结果,比如arr[8]={0,4,7,5,2,6,1,3} 
  7.     private int[] array = new int[max]; 
  8.  
  9.     static int count = 0; 
  10.  
  11.     public static void main(String[] args) { 
  12.         Queen8 queen8 = new Queen8(); 
  13.         queen8.check(0); 
  14.         System.out.printf("总共%d摆法\n",count);//92种 
  15.     } 
  16.  
  17.     //放置第n个皇后 
  18.     public void check(int n) { 
  19.         if (n == max) {//n=8 说明前面已经放好 
  20.             print(); 
  21.             count++; 
  22.             return
  23.         } 
  24.         //依次放入皇后并判断是否冲突 
  25.         for (int i = 0; i < max; i++) { 
  26.             //先把当前的皇后n,放到改行的第1列 
  27.             array[n] = i; 
  28.             //判断当放置第n个皇后到第i列是,是否冲突. 
  29.             if (judge(n)) { 
  30.                 //接着放n+1皇后,开始递归 
  31.                 check(n + 1); 
  32.             } 
  33.         } 
  34.     } 
  35.  
  36.     //查看当放置第n个皇后时,就去检测该皇后是否前面已经摆放的皇后冲突 
  37.     private boolean judge(int n) { 
  38.         for (int i = 0; i < n; i++) { 
  39.             //array[i] == array[n] 表示第n个皇后是否与之前的皇后在同一列 
  40.             //Math.abs(n - i) == Math.abs(array[n] - array[i]) 表示第n个皇后是否与之前在同一个斜线 
  41.             if (array[i] == array[n] || Math.abs(n - i) == Math.abs(array[n] - array[i])) { 
  42.                 return false
  43.             } 
  44.         } 
  45.         return true
  46.     } 
  47.  
  48.     //将皇后摆放的位置输出 
  49.     public void print() { 
  50.         for (int i = 0; i < array.length; i++) { 
  51.             System.out.print(array[i] + " "); 
  52.         } 
  53.         System.out.println(); 
  54.     } 

 【编辑推荐】

 

责任编辑:姜华 来源: 今日头条
相关推荐

2021-05-12 09:07:09

Java数据结构算法

2021-03-09 06:30:32

JAVA数据结构算法

2021-03-18 08:44:20

Java数据结构算法

2021-04-27 06:21:29

Java数据结构算法

2021-03-26 08:40:28

Java数据结构算法

2021-03-12 09:13:47

Java数据结构算法

2021-03-23 08:33:22

Java数据结构算法

2021-03-10 08:42:19

Java数据结构算法

2021-03-08 06:28:57

JAVA数据结构与算法稀疏数组

2021-03-17 09:27:36

Java数据结构算法

2021-04-07 09:26:37

Java数据结构算法

2021-04-16 09:40:52

Java数据结构算法

2021-04-15 09:36:44

Java数据结构算法

2021-04-22 10:07:45

Java数据结构算法

2021-03-14 08:27:40

Java数据结构算法

2021-05-13 07:34:56

Java数据结构算法

2021-04-23 09:12:09

Java数据结构算法

2021-03-11 08:53:20

Java数据结构算法

2021-03-24 10:41:04

Java数据结构算法

2021-05-08 08:28:38

Java数据结构算法
点赞
收藏

51CTO技术栈公众号