【一Go到底】第十七天---函数的递归调用

103 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第17天,点击查看活动详情

一、递归调用简介

1.1 什么是递归调用

一个函数在函数体内又调用了本身,我们称为递归调用

1.2 递归小案例

package main

import "fmt"

func mless(n int) {
	if n > 2 {
		n--
		mless(n)
	}
	fmt.Println("n = ", n)
}

func main() {

	// 使用 mless函数
	// 传入5 -- > 满足n>2 ---> n--等于4,再次调用mless
	// 第二次调用 传入4 ---> 满足 n>2 --> n--等于3 ,再次调用mless
	// 第三次调用 传入3 ---> 满足 n>3 --> n--等于2 ,再次调用mless
	// 第四次调用 传入2 ---> 不满足 n>2 --> n--等于1 ,执行fmt打印 输出2----退出当前栈
	// 结束第四次调用,返回到第三次,退出第三次中的if 语句,执行 fmt 打印 n =2
	// 结束第三次调用,返回到第二次,退出第二次中的if,执行fmt 打印 n=3
	// 结束第二次调用,返回第一次传入的5,退出第一次的if,执行fmt打印n=4
    
    // 最终输出为
    // n=2 n=2 n=3 n=4
    mless(5)
}

1.3 函数递归原则

  • 执行一个函数时,就创建一个 新的受保护的独立空间(新函数栈)
  • 函数的局部变量是独立的,不会相互影响
  • 递归必须向退出递归的条件逼近,否则就是无限递归,死龟了:)
  • 当一个函数执行完毕,或者遇到return, 就会返回,遵守谁调用,就将结果返回给谁,同时当函数执行完毕或者返回时,该函数本身也会被系统销毁

二、函数递归案例

2.1 斐波那契数列

请使用递归的方式,求出斐波那契数1,1,2,3,5,8,3....,给你一个整数n,求出它的值是多少?

package main

import "fmt"

func fib(num int) int {
	if num == 1 || num == 2 {
		return num
	} else {
		return fib(num-1) + fib(num-2)
	}
}
func main() {
	result := fib(5)
	fmt.Println(result)
}


2.2 求函数值

已知f(1)=3; f(n)= 2*f(n-1)+1;请使用递归的思想编程,求出f(n)的值?

package main

import "fmt"

func f(n int) int {
	if n == 1 {
		return 3
	} else {
		return 2*f(n-1) + 1
	}
}

func main() {
	// f(1) 测试
	fmt.Println("f(1)= ", f(1))
	fmt.Println("f(5)= ", f(5))

}


2.3 猴子吃桃问题

题3:猴子吃桃子问题

有一堆桃子,猴子第一天吃了其中的一半,并再多吃了一个!以后每天猴子都吃其中的一半,然后再多吃一个。当到第十天时,想再吃时(还没吃),发现只有1个桃子了。问题:最初共多少个桃子?

解析

  1. 第十天只有一个桃
  2. 第九天 = (第十天 +1 ) * 2
  3. 第n天桃子 peach(n) = (peach(n+1)+1)*2
package main

import "fmt"

func peach(d int) int {
	// d范围应该在 1-10
	if d > 10 || d < 1 {
		fmt.Println("天数错误.....")
		return 0
	}
	if d == 10 {
		return 1
	} else {
		return (peach(d+1) + 1) * 2
	}
}
func main() {

	// 第一天桃子
	fmt.Println("第一天的桃子数量: ", peach(1))
}