Go学习笔记—递归(阶乘、斐波那契数列、汉诺塔问题)

Go学习笔记—递归


如有问题,请留言指正!谢谢观看


1.递归的定义

一个程序在运行过程中调用自己。

通常在一个.go的文件中,使用函数来达到循环调用的情况。

构成递归具备的条件:

  1. 子问题与原始问题为同样的事,且更为简单。
  2. 必须要有递归调用的出口,也就是递归函数结束的条件。

递归的使用一般都会有规律。

2.递归的示例

1.阶乘案列

9的阶乘,可以化简为9!=9x8x7x6x5x4x3x2x1x1,首先0的阶乘是1,因此阶乘递归结束的条件就是

//阶乘递归结束的条件,f(0)=1
if n==0 {
    
    
    return 1
}
  • n==1时,数学公式为1*f(1-1)
  • n==2时,数学公式为2*f(2-1)*f(1-1)
  • 所以第n项时,数学公式为n*f(n-1)*f(n-1-1)*...*f(n-1-1-...-1) = n*f(n-1)*f(n-2)*...*f(1)*f(0)
func fact(n int) int{
    
    
    if n==0{
    
    
        return 1
    }
    return n*fact(n-1)
}

//7!=5040

2.Fibonacci数列

斐波那契数列的形式为:0、1、1、2、3、5、8、13、21、34、……

  • 数学表示为:f(0)=0、f(1)=1、f(2)=f(2-1)+f(2-2)、…
  • 通项公式为:F(0)=0、F(1)=1、F(n)=F(n-1)+F(n-2)

递归结束的条件是F(0)=0、F(1)=1

//斐波那契数列递归结束的条件
if n==0{
    
    
    return 0
}else if n==1{
    
    
    return 1
}

使用递归的完整函数为:

func fibonacci(n int) int{
    
    
    if n==0{
    
    
        return 0
    }else if n==1{
    
    
        return 1
    }
    return fibonacci(n-1)+fibonacci(n-2)
}

//3 = 2

3.汉诺塔(Hanoi)问题

汉诺塔问题是将一些盘子从A柱移动到C柱,移动过程中保证大盘子永远在小盘子下面,移动过程可以借助B柱,将A柱的盘子全部移动到C柱上。

拆解步骤:

  • 当A柱只有一个盘子时,直接将盘子从A柱移动到C柱,这种情况就是递归结束的条件

    //汉诺塔问题递归结束的条件
    if n==1{
          
          
        hanoiMove(A,C)
        //从A->C
    }
    
  • 当A柱有两个盘子时,先A->B,再A->C,再B->C

使用递归的完整函数为:

//定义全局变量,获取移动盘子的次数
var count int
//定义移动函数,并统计移动次数
func hanoiMove(a,b string){
    
    
    count ++
    fmt.Printf("%s->%s",a,b)
}
//定义递归函数,判断移动的顺序
func hanoi(n int,a,b,c string){
    
    
    if n==1{
    
    
        hanoiMove(a,c)
    }else{
    
    
        hanoi(n-1,a,c,b) //把A移到B
        hanoiMove(a,c)
        hanoi(n-1,b,a,c) //把B移到C
    }
}


func main(){
    
    
    a,b,c := "A","B","C"
    hanoi(2,a,b,c)
    fmt.Println(count)
}

//A->B
//A->C
//B->C
//3

猜你喜欢

转载自blog.csdn.net/weixin_46435420/article/details/119411637