递归调用机制
1 public class RecursionTest { 2 3 public static void main(String[] args) { 4 // TODO Auto-generated method stub 5 //通过打印问题,回顾递归调用机制 6 test(4); 7 8 //int res = factorial(3); 9 //System.out.println("res=" + res); 10 } 11 //打印问题. 12 public static void test(int n) { 13 if (n > 2) { 14 test(n - 1); 15 } //else { 16 System.out.println("n=" + n); 17 // } 18 } 19 //阶乘问题 20 public static int factorial(int n) { 21 if (n == 1) { 22 return 1; 23 } else { 24 return factorial(n - 1) * n; // 1 * 2 * 3 25 } 26 } 27 28 29 }
递归求最大值
1 public class Text { 2 public static void main(String[] args) { 3 int arr[] = new int[] {1,34,5,4,32,2,38,6,7,8}; 4 int Max= mergeSort(arr,0,arr.length-1); 5 for(int i = 0; i< arr.length; i++) { 6 System.out.println(arr[i]); 7 } 8 9 System.out.println(Max); 10 } 11 12 public static int mergeSort(int[] arr, int l, int r) { 13 if (l == r) { 14 return arr[l]; 15 } 16 int mid = ((r + l) >> 1); 17 int Getrmax = mergeSort(arr, l, mid); 18 int Fetlmax = mergeSort(arr, mid+1, r); 19 return Math.max(Getrmax, Fetlmax); 20 } 21 22 }
猴子吃桃
1 public class Text2 { 2 //猴子吃桃问题 3 public static int tao(int n) { 4 if(n == 10) { // 终止条件 5 return 1; 6 } 7 return (tao(n + 1) + 1 * 2); // 把范围缩小到最小 两天 求变大时 8 9 } 10 public static void main(String[] args) { 11 System.out.println(tao(1)); 12 } 13 }
回溯问题
1 public class MiGong { 2 3 public static void main(String[] args) { 4 // 先创建一个二维数组,模拟迷宫 5 // 地图 6 int[][] map = new int[8][7]; 7 // 使用1 表示墙 8 // 上下全部置为1 9 for (int i = 0; i < 7; i++) { 10 map[0][i] = 1; 11 map[7][i] = 1; 12 } 13 14 // 左右全部置为1 15 for (int i = 0; i < 8; i++) { 16 map[i][0] = 1; 17 map[i][6] = 1; 18 } 19 //设置挡板, 1 表示 20 map[3][1] = 1; 21 map[3][2] = 1; 22 // map[1][2] = 1; 23 // map[2][2] = 1; 24 25 // 输出地图 26 System.out.println("地图的情况"); 27 for (int i = 0; i < 8; i++) { 28 for (int j = 0; j < 7; j++) { 29 System.out.print(map[i][j] + " "); 30 } 31 System.out.println(); 32 } 33 34 //使用递归回溯给小球找路 35 //setWay(map, 1, 1); 36 setWay2(map, 1, 1); 37 38 //输出新的地图, 小球走过,并标识过的递归 39 System.out.println("小球走过,并标识过的 地图的情况"); 40 for (int i = 0; i < 8; i++) { 41 for (int j = 0; j < 7; j++) { 42 System.out.print(map[i][j] + " "); 43 } 44 System.out.println(); 45 } 46 47 } 48 49 //使用递归回溯来给小球找路 50 //说明 51 //1. map 表示地图 52 //2. i,j 表示从地图的哪个位置开始出发 (1,1) 53 //3. 如果小球能到 map[6][5] 位置,则说明通路找到. 54 //4. 约定: 当map[i][j] 为 0 表示该点没有走过 当为 1 表示墙 ; 2 表示通路可以走 ; 3 表示该点已经走过,但是走不通 55 //5. 在走迷宫时,需要确定一个策略(方法) 下->右->上->左 , 如果该点走不通,再回溯 56 /** 57 * 58 * @param map 表示地图 59 * @param i 从哪个位置开始找 60 * @param j 61 * @return 如果找到通路,就返回true, 否则返回false 62 */ 63 public static boolean setWay(int[][] map, int i, int j) { 64 if(map[6][5] == 2) { // 通路已经找到ok 65 return true; 66 } else { 67 if(map[i][j] == 0) { //如果当前这个点还没有走过 68 //按照策略 下->右->上->左 走 69 map[i][j] = 2; // 假定该点是可以走通. 70 if(setWay(map, i+1, j)) {//向下走 71 return true; 72 } else if (setWay(map, i, j+1)) { //向右走 73 return true; 74 } else if (setWay(map, i-1, j)) { //向上 75 return true; 76 } else if (setWay(map, i, j-1)){ // 向左走 77 return true; 78 } else { 79 //说明该点是走不通,是死路 80 map[i][j] = 3; 81 return false; 82 } 83 } else { // 如果map[i][j] != 0 , 可能是 1, 2, 3 84 return false; 85 } 86 } 87 } 88 89 //修改找路的策略,改成 上->右->下->左 90 public static boolean setWay2(int[][] map, int i, int j) { 91 if(map[6][5] == 2) { // 通路已经找到ok 92 return true; 93 } else { 94 if(map[i][j] == 0) { //如果当前这个点还没有走过 95 //按照策略 上->右->下->左 96 map[i][j] = 2; // 假定该点是可以走通. 97 if(setWay2(map, i-1, j)) {//向上走 98 return true; 99 } else if (setWay2(map, i, j+1)) { //向右走 100 return true; 101 } else if (setWay2(map, i+1, j)) { //向下 102 return true; 103 } else if (setWay2(map, i, j-1)){ // 向左走 104 return true; 105 } else { 106 //说明该点是走不通,是死路 107 map[i][j] = 3; 108 return false; 109 } 110 } else { // 如果map[i][j] != 0 , 可能是 1, 2, 3 111 return false; 112 } 113 } 114 } 115 116 }
作业:
//待添加
八皇后问题
1 public class Queue8 { 2 3 //定义一个max表示共有多少个皇后 4 int max = 8; 5 //定义数组array, 保存皇后放置位置的结果,比如 arr = {0 , 4, 7, 5, 2, 6, 1, 3} 6 int[] array = new int[max]; 7 static int count = 0; 8 static int judgeCount = 0; 9 public static void main(String[] args) { 10 //测试一把 , 8皇后是否正确 11 Queue8 queue8 = new Queue8(); 12 queue8.check(0); 13 System.out.printf("一共有%d解法", count); 14 System.out.printf("一共判断冲突的次数%d次", judgeCount); // 1.5w 15 16 } 17 18 19 20 //编写一个方法,放置第n个皇后 21 //特别注意: check 是 每一次递归时,进入到check中都有 for(int i = 0; i < max; i++),因此会有回溯 22 private void check(int n) { 23 if(n == max) { //n = 8 , 其实8个皇后就既然放好 24 print(); 25 return; 26 } 27 28 //依次放入皇后,并判断是否冲突 29 for(int i = 0; i < max; i++) { 30 //先把当前这个皇后 n , 放到该行的第1列 31 array[n] = i; 32 //判断当放置第n个皇后到i列时,是否冲突 33 if(judge(n)) { // 不冲突 34 //接着放n+1个皇后,即开始递归 35 check(n+1); // 36 } 37 //如果冲突,就继续执行 array[n] = i; 即将第n个皇后,放置在本行得 后移的一个位置 38 } 39 } 40 41 //查看当我们放置第n个皇后, 就去检测该皇后是否和前面已经摆放的皇后冲突 42 /** 43 * 44 * @param n 表示第n个皇后 45 * @return 46 */ 47 private boolean judge(int n) { 48 judgeCount++; 49 for(int i = 0; i < n; i++) { 50 // 说明 51 //1. array[i] == array[n] 表示判断 第n个皇后是否和前面的n-1个皇后在同一列 52 //2. Math.abs(n-i) == Math.abs(array[n] - array[i]) 表示判断第n个皇后是否和第i皇后是否在同一斜线 53 // n = 1 放置第 2列 1 n = 1 array[1] = 1 54 // Math.abs(1-0) == 1 Math.abs(array[n] - array[i]) = Math.abs(1-0) = 1 55 //3. 判断是否在同一行, 没有必要,n 每次都在递增 56 if(array[i] == array[n] || Math.abs(n-i) == Math.abs(array[n] - array[i]) ) { 57 return false; 58 } 59 } 60 return true; 61 } 62 63 //写一个方法,可以将皇后摆放的位置输出 64 private void print() { 65 count++; 66 for (int i = 0; i < array.length; i++) { 67 System.out.print(array[i] + " "); 68 } 69 System.out.println(); 70 } 71 72 }