尾递归不是伪递归啊喂!

  • 概念:
    • 如果一个函数中所有递归形式的调用都出现在函数的末尾,我们称这个递归函数是尾递归的。当递归调用是整个函数体中最后执行的语句且它的返回值不属于表达式的一部分时,这个递归调用就是尾递归。尾递归函数的特点是在回归过程中不用做任何操作,这个特性很重要,因为大多数现代的编译器会利用这种特点自动生成优化的代码。

  • 尾递归优势:
    • 与普通递归相比,由于尾递归的调用处于方法的最后,因此方法之前所积累下的各种状态对于递归调用结果已经没有任何意义,因此完全可以把本次方法中留在堆栈中的数据完全清除,把空间让给最后的递归调用。这样的优化便使得递归不会在调用堆栈上产生堆积,意味着即时是“无限”递归也不会让堆栈溢出。这便是尾递归的优势。

  • 举个例子:
    以阶乘为例:
    正常递归:
    func formalRecursion(n int) int {
        if n<=0 {
            return 0
        }
        if n==1 {
            return 1
        }
        return n*formalRecursion(n-1)
    }
    
    尾递归:
    var a int = 1
    func tailRecursion(n int,a int) int {
        if n<=0 {
            return 0
        }
        if n==1 {
            return a
        }
        return tailRecursion(n-1,n* a)
    }  
    ```
只可惜。。。golang的编译器对尾递归并没有优化。。。
那么golang这样写尾递归:
// 这个是有进行优化的。因为recursionChannel函数执行完毕后,直接就销毁了,没有接着保留堆栈
func recursionChannel(n int, a int, result chan int) {
    a = n*a
    if n <= 0 {
        result <- 0
        return 
    }
    if n == 1 {
        result <- a
        return
    }
    go recursionChannel(n-1, a, result)  // 无需等待返回
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值