1.定义
所谓递归,简单点来说,就是一个函数直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解。
我们可以把” 递归 “比喻成 “查字典 “,当你查一个词,发现这个词的解释中某个词仍然不懂,于是你开始查这第二个词。可惜,第二个词里仍然有不懂的词,于是查第三个词,这样查下去,直到有一个词的解释是你完全能看懂的,那么递归走到了尽头,然后你开始后退,逐个明白之前查过的每一个词,最终,你明白了最开始那个词的意思。(摘自知乎的一个回答)
如果调用函数的情况下,那么就是自己调用自己.
2.运用
2.1 递归函数实现:
package main
import "fmt"
/**
* sums切片从起始位置@l相加到结尾
* @arr 切片
* @l 相加开始切片索引的int
* sum(arr[0],...,arr[5])=arr[0]+sum(arr[1],...,arr[5]) l=0
* sum(arr[1],...,arr[5])=arr[1]+sum(arr[2],...,arr[5]) l=1
* sum(arr[5],0)=arr[5]+sum([]) l=5
*/
func sums(arr []int, l int) int {
if l >= len(arr) {
return 0
} else {
return arr[l] + sums(arr, l+1)
}
}
func main() {
l := []int{2, 3, 4, 5, 6, 7}
fmt.Println(sums(l, 4))
}
其中,递归的组成是由两部分组成的,基本问题和转化问题,如图所示:
2.2 递归的微观解读(其实和函数调用是一样的,只是这里面是自己调用自己的):
2.3 递归的调用是需要调用系统栈的,一定要有基本问题的应答,否则会因为系统栈溢满而报错
2.4 梯队展示:
package main
import "fmt"
/**
* sums切片从起始位置@l相加到结尾
* @arr 切片
* @l 相加开始切片索引的int
* @depth 调用递归的深度
* sum(arr[0],...,arr[5])=arr[0]+sum(arr[1],...,arr[5]) l=0
* sum(arr[1],...,arr[5])=arr[1]+sum(arr[2],...,arr[5]) l=1
* sum(arr[5],0)=arr[5]+sum([]) l=5
*/
func sums(arr []int, l, depth int) (res int) {
if l == len(arr) {
return 0
} else {
res := arr[l] + sums(arr, l+1, depth+1)
dumper(depth)
fmt.Println("第", len(arr)-depth, "次调用,调用的结果是:", res)
return res
}
}
func dumper(depth int) {
for a := 0; a < depth; a++ {
fmt.Print("--")
}
}
func main() {
l := []int{2, 3, 4, 5, 6, 7}
fmt.Println(sums(l, 0, 0))
}
梯队调用展示: