看个实际应用场景
迷宫问题(回溯)
递归的概念
简单的说: 第归就是函数/方法自己调用自己,每次调用时传入不同的变量.第归有助于编程者解决复杂的问题,同时可以让代码变得简洁。
递归快速入门
我列举两个小案例,来帮助大家理解递归,递归在讲函数时已经讲过(当时讲的相对比较简单),这里在给大家回顾一下递归调用机制
-
打印问题
-
阶乘问题
-
打印问题的代码和递归调用的机制分析
package com.atguigu.chapter18.recursive
object RecursiveDemo { def main(args: Array[String]): Unit = {
test(4) // 2, 3, 4 // 2 }
def test(n: Int): Unit = { if (n > 2) { test(n -1) } else { println("n=" + n) } }
} |
-
上面代码的分析示意图
递归用于解决什么样的问题
-
各种数学问题如: 8皇后问题 , 汉诺塔, 阶乘问题, 迷宫问题, 球和篮子的问题(google编程大赛)
-
将用栈解决的问题-->第归代码比较简洁
-
执行一个函数时,就创建一个新的受保护的独立空间(新函数栈)
-
函数的局部变量是独立的,不会相互影响
-
递归必须向退出递归的条件逼近,否则就是无限递归,死龟了:)
-
当一个函数执行完毕,或者遇到return,就会返回,遵守谁调用,就将结果返回给谁,同时当函数执行完毕或者返回时,该函数本身也会被系统销毁
举一个比较综合的案例,迷宫问题
-
思路分析
-
代码实现
package com.atguigu.chapter18.recursive
object MiGong { def main(args: Array[String]): Unit = { //地图 val map = Array.ofDim[Int](8, 7) //上下全部置1 for (i <- 0 until 7) { map(0)(i) = 1 map(7)(i) = 1 } //左右全部置1 for (i <- 0 until 8) { map(i)(0) = 1 map(i)(6) = 1 }
//设置挡板 map(3)(1) = 1 map(3)(2) = 1 map(1)(2) = 1 map(2)(2) = 1 //打印地图 for (i <- 0 until 8) { for (j <- 0 until 7) { print(map(i)(j) + " ") } println() }
//测试方法 setWay(map, 1, 1)
//打印新地图 println() for (i <- 0 until 8) { for (j <- 0 until 7) { print(map(i)(j) + " ") } println() } }
//使用递归回溯来找路 //1. map 表示地图 //2. i j 是指定从地图的哪个点开始出发 (1,1) //3. 约定元素的值 0: 可以走还没有走 1 : 墙 2: 表示可以走 3 : 表示已经走过,但是是死路 //确定一个策略: 下=》右=》上=》左 //修改策略上=》右=》下=》左
def setWay(map: Array[Array[Int]], i: Int, j: Int): Boolean = { if (map(6)(5) == 2) { // 表示路已经找到了 return true } else { if (map(i)(j) == 0) { // 0: 可以走还没有走 //这里开始递归回溯 map(i)(j) = 2 // 认为该点是可以走通,但是不一定 if (setWay(map, i - 1, j)) { // 上找 return true } else if (setWay(map, i, j + 1)) { //右 return true } else if (setWay(map, i + 1, j)) { //下 return true } else if (setWay(map, i, j - 1)) { //左 return true } else { //走不通 map(i)(j) = 3 return false } } else { //如果map(i)(j)!=0 //则值 1,2,3 //????? return false } } } } |