递归
1、递归的概念
简单说,递归就是函数/方法自己调用自己,每次调用时传入不同的变量,递归有助于编程者解决复杂的问题,同时可以让代码变得简洁。
2、简单案例
2.1、分析下面代码的输出
func test(n int){
if n > 2{
n--
test(n)
}
fmt.println(n)
}
func main(){
n := 4
test(n)
}
(1) 首先,主函数执行,获取到一片内存,初始化变量n, 此时n = 4, 将n作为参数传给test()。调用test(),这时候主函数中的test()分得一部分内存。
(2) 进入test()函数,判断n 是否大于2,满足,对n进行减1操作后,此时n =3,继续调用test(),这时候test()又分到一块内存。若不满足,执行println(n)语句。
(3) 所以,最后输出应该是 2 2 3
2.2、分析下面代码的输出
func test(n int){
if n > 2{
n--
test(n)
}else{
fmt.println(n)
}
}
func main(){
n := 4
test(n)
}
// 2
3、 递归需要遵守的重要原则
- 执行一个函数时,就创建一个新的受保护的独立空间(新函数栈)
- 函数的局部变量是独立的,不会相互影响,如果希望各个函数栈使用同一个数据,使用引用传递
- 递归必须向退出的条件逼近,否则就是无限递归
- 当一个函数执行完毕,或遇到return,就会返回,遵守谁调用,就将结果返回给谁,同时函数执行完毕或者返回时,该函数本身也会被系统销毁。
4、迷宫问题
package main
import "fmt"
// 编写一个函数,完成老鼠找出路
func SetWay (myMap *[8][7]int, i, j int) bool {
if myMap[6][5] == 2 {
return true
}else {
// 说明要继续找
if myMap[i][j] == 0 { // 如果这个点是可以探测
// 假设这个是可以通的,需要探测 下右上左
myMap[i][j] = 2
if SetWay(myMap,i + 1,j){ // 上
return true
} else if SetWay(myMap, i, j + 1){ // 右
return true
} else if SetWay(myMap,i + 1, j){ // 上
return true
} else if SetWay(myMap,i, j - 1){ // 左
return true
} else { // 死路
myMap[i][j] = 3
return false
}
} else { // 说明这个点不能探测,为1,是墙
return false
}
}
}
func main(){
// 二维数组模拟迷宫
/*
1、如果元素的值为1,就是墙
2、如果元素的值为0,是没有走过的点
3、如果元素的值为2,是一个通路
4、如果元素的值为3,曾经走过,但是不通
*/
var mymap [8][7]int
// 地图的最上和最下设置为1
for i := 0; i < 7; i ++{
mymap[0][i] = 1
mymap[7][i] = 1
}
// 地图的最左最右设置为1
for i := 0; i < 8; i ++ {
mymap[i][0] = 1
mymap[i][6] = 1
}
mymap[3][1] = 1
mymap[3][2] = 1
// 用于测试死路
// mymap[1][2] = 1
// mymap[2][2] = 1
SetWay(&mymap,1,1)
for i := 0; i < 8; i ++ {
for j := 0; j < 7; j ++{
fmt.Print(mymap[i][j]," ")
}
fmt.Println()
}
}