函数递归调用

基本介绍:

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

代码1:

package main

import (
"fmt"
)

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

func main() {

  test(4)
}

上面代码的内存分析图:

代码2:

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

func main() {

  test2(4)
}

对上面代码分析的示意图:

函数递归需要遵守的重要原则:

1)执行一个函数时,就创建一个新的受保护的独立空间(新函数栈)

2)函数的局部变量是独立的,不会相互影响

3)递归必须向退出递归的条件逼近,否则就是无限递归,死龟了:)

4)当一个函数执行完毕,或者遇到return,就会返回,遵守谁调用,就将结果返回给谁。同时当函数执行完毕或者返回时,该函数本身也会被系统销毁。

练习题:

题1: 斐波那契数

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

思路:
  1)当 n == 1 || n == 2,返回1
  2)当 n >= 2,返回前面两个数的和 f(n-1) + (n-2)

代码:

package main
import "fmt"

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

func fbn(n int) int {
  if (n == 1 || n == 2) {
    return 1
  } else {
    return fbn(n - 1) + fbn(n - 2)
  }
}
func main() {
  res := fbn(3)
  //测试
  fmt.Println("res=" ,res)   //2
  fmt.Println("res=" ,fbn(4))   //3
  fmt.Println("res=" ,fbn(5))   //5
  fmt.Println("res=" ,fbn(6))   //8
}

 


题2:求函数值

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

思路:
  直接使用给出的表达式即可完成案例。

代码:

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

func main() {

  //测试一下
  fmt.Println("f(1)=", f(1)) //3
  fmt.Println("f(5)=", f(5)) //63
}


题3:猴子吃桃子问题

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


思路分析:

  1)第10天只有1个桃子了
  2)第9天有几个桃子 = (第10天桃子数量 + 1)* 2
  3)规律:第n天的桃子数据 peach(n) = (peach(n+1)+1) *2 //peach(n+1) 天数的结果数量最后+1 在乘以2

代码:

func peach(n int) int {
  if n > 10 || n < 1 {
    fmt.Println("输入的天数不对")
    return 0   //返回0表示没有得到正确数量
  }
  if n == 10 {
    return 1
  } else {
    return (peach(n+1) + 1) * 2
  }
}

func main() {
  fmt.Println("第1天桃子数量是=", peach(1))
}

上面代码的内存分析图:

 

posted @ 2019-08-13 00:46  我是一只忙碌的小青蛙  阅读(496)  评论(0编辑  收藏  举报