博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java递归应用
阅读量:4709 次
发布时间:2019-06-10

本文共 4784 字,大约阅读时间需要 15 分钟。

一、概念

  简单的说: 递归就是方法自己调用自己

  递归有助于解决复杂的问题,可以让代码变得简洁

二、能解决什么样的问题

    

 

三、递归需要遵守的重要规则

 

四、迷宫问题

  

  说明:

  1)小球得到的路径,和程序员设置的查找策略有关,即:上 -> 下 -> 左 -> 右

  2)  在得到小球路径时,可以先使用(上下左右),在改为(上右下左),看路径是否有变化

  3)测试回溯现象

  4)最短路径求法?

  代码: 

1 public class MiGong { 2     public static void main(String[] args) { 3         // 先创建一个二维数组,模拟迷宫 4         int[][] map = new int[8][7]; 5         // 使用1 表示墙 6         // 上下全部置为1 7         for (int i = 0; i < map[0].length; i++) { 8             map[0][i] = 1; 9             map[7][i] = 1;10         }11         // 左右全部置为112         for (int i = 1; i < map.length - 1; i++) {13             map[i][0] = 1;14             map[i][6] = 1;15         }16         //设置挡板, 1 表示17         map[3][1] = 1;18         map[3][2] = 1;19         // 输出地图20         for (int i = 0; i < map.length; i++) {21             for (int j = 0; j < map[i].length; j++) {22                 System.out.print(map[i][j] + "\t");23             }24             System.out.println();25         }26         System.out.println("------------------------");27         //使用递归回溯给小球找路28         findWay(map, 1, 1);29         //输出新的地图, 小球走过,并标识过的递归30         for (int i = 0; i < map.length; i++) {31             for (int j = 0; j < map[i].length; j++) {32                 System.out.print(map[i][j] + "\t");33             }34             System.out.println();35         }36     }37     //使用递归回溯来给小球找路38     //说明39     //1. map 表示地图40     //2. i,j 表示从地图的哪个位置开始出发 (1,1)41     //3. 如果小球能到 map[6][5] 位置,则说明通路找到.42     //4. 约定: 当map[i][j] 为 0 表示该点没有走过 当为 1 表示墙  ; 2 表示通路可以走 ; 3 表示该点已经走过,但是走不通43     //5. 在走迷宫时,需要确定一个策略(方法) 下->右->上->左 , 如果该点走不通,再回溯44 45     /**46      * @param map47      * @param i   从哪个位置开始找48      * @param j49      * @return 如果找到通路,就返回true, 否则返回false50      */51     public static boolean findWay(int[][] map, int i, int j) {52         if (map[6][5] == 2) {53             return true;54         } else {55             //如果当前点没走过56             if (map[i][j] == 0) {57                 //假定可以走通58                 map[i][j] = 2;59                 //下{
60 if (findWay(map, i+1, j )) {61 return true;62 }63 //右64 else if (findWay(map, i , j+1)) {65 return true;66 }67 //上68 else if (findWay(map, i - 1, j)) {69 return true;70 }71 //左72 else if (findWay(map, i, j - 1)) {73 return true;74 }75 else {76 //说明该点是走不通,是死路77 map[i][j] = 3;78 return false;79 }80 // 如果map[i][j] != 0 , 可能是 1, 2, 381 } else {82 return false;83 }84 85 }86 }87 }

 

五、八皇后问题(回溯算法)

   1、概述

  问题,是一个古老而著名的问题,是的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。 认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。计算机发明后,有多种计算机语言可以解决此问题。

  

  2、思路分析 

  3、说明

  理论上应该创建一个二维数组来表示棋盘,但实际可以通过算法,用一个一位数组即可解决问题

  arr[8] = {0, 4, 7,5,2,6,1,3},对应的下标表示第几行,即第几个皇后,arr[i] = val, val 表示第i+1个皇后,放在i+1行的第val+1列

  4、代码

1 public class Queen8 { 2     //定义一个max表示共有多少个皇后8 3     final static int max = 8; 4     //定义数组array, 保存皇后放置位置的结果,比如 arr = {0 , 4, 7, 5, 2, 6, 1, 3} 5     static int[] arr = new int[max]; 6     //记录不冲突的次数 7      static int count; 8     //总判断次数 9     static int sumCount;10 11     public static void main(String[] args) {12         check(0);13         System.out.printf("共有%d种走法,一共判断%d次\n",count,sumCount);14     }15 16     //编写一个方法,放置第n个皇后17     //特别注意: check 是 每一次递归时,进入到check中都有  for(int i = 0; i < max; i++),因此会有回溯18     public static void check(int n) {19         //n = 8 , 其实8个皇后就既然放好20         if (n == max) {21             print();22             return;23         }24         //依次放入皇后,并判断是否冲突25         for (int i = 0; i < max; i++) {26             //先把当前这个皇后 n , 放到该行的第1列27             arr[n]=i;28             //判断当放置第n个皇后到i列时,是否冲突29             if(judge(n)){ // 不冲突30                 //接着放n+1个皇后,即开始递归31                 check(n+1);32             }33             //如果冲突,就继续执行 array[n] = i; 即将第n个皇后,放置在本行得 后移的一个位置34         }35 36     }37 38     //查看当我们放置第n个皇后, 就去检测该皇后是否和前面已经摆放的皇后冲突39     public static boolean judge(int n) {40         sumCount++;41         // 说明42         //1. array[i] == array[n]  表示判断 第n个皇后是否和前面的n-1个皇后在同一列43         //2. Math.abs(n-i) == Math.abs(array[n] - array[i]) 表示判断第n个皇后是否和第i皇后是否在同一斜线44         // n = 1  放置第 2列 1 n = 1 array[1] = 145         // Math.abs(1-0) == 1  Math.abs(array[n] - array[i]) = Math.abs(1-0) = 146         //3. 判断是否在同一行, 没有必要,n 每次都在递增47         for (int i = 0; i 

 

转载于:https://www.cnblogs.com/hyunbar/p/11291073.html

你可能感兴趣的文章
实验3 SQL注入原理-万能密码注入
查看>>
redis cluster
查看>>
feign传输String json串 自动转义 \ 解决方法
查看>>
本站已稳定运行了XX天,网页时间显示功能实现方法
查看>>
实习的开始阶段
查看>>
搭建第一个node服务器
查看>>
团队冲刺个人总结8
查看>>
Asp.Net Mvc Area二级域名
查看>>
requirements基本使用
查看>>
C++ Boost入门
查看>>
android:intent flags
查看>>
Vue疑难杂症
查看>>
spring boot 错误处理之深度历险
查看>>
MySQL对于有大量重复数据表的处理方法
查看>>
Android应用开发学习笔记之多线程与Handler消息处理机制
查看>>
ubuntu 设置环境变量
查看>>
JSTL详解(一)
查看>>
Manacher 算法
查看>>
Linux磁盘及文件系统(三)Linux文件系统
查看>>
SDWebImage源码阅读(二)NSData+ImageContentType
查看>>