Golang 尾递归和递归比起来优势在哪?

本文探讨了Golang中尾递归与普通递归的区别,强调了尾递归在效率和内存占用上的优势。尾递归通过在递归调用后立即返回结果,避免了不必要的运算和堆栈空间的消耗,降低了栈溢出的风险。通过实例展示了如何实现尾递归求阶乘,解释了尾递归优化的概念。理解并掌握尾递归有助于编写更高效的Golang代码。
摘要由CSDN通过智能技术生成

Golang 尾递归和递归比起来优势在哪?

Golang轻松学习


一、递归与尾递归是什么?

1.递归

递归就是一个函数直接或间接地调用自身,是为直接或间接递归。递归主要是通过把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归就是用少量的程序来描述出解题过程所需要的多次重复计算。

2.尾递归

而尾递归就是一个函数中所有递归形式的调用都出现在函数的末尾。也就是说,程序每递归一次就算出相应的结果,函数调用出现在调用者函数的尾部, 没有必要去保存任何局部变量。尾递归函数的特点是在回归过程中不用做任何操作。

二、详细代码

当我们的问题时求阶层时:

1 * 2 * 3 * 4 N

1.递归

代码如下(示例):

package main

import "fmt"

func Rescue(n int) int {

	if n == 0 {
		return 1
	}

	// 进入下一层
	// 例:5 * Rescue(5-1)
	// 再下一层
	// 例:5 * 4 * Rescue(4-1)
	return n * Rescue(n-1)
}

func main() {
	fmt.Println(Rescue(5))
}

函数不断地调用本身,并且在下次调用时还会乘以一个变量n,这就是递归。在上面代码中,Rescue(5) 会不断调用自身,最终将自身改变为 5 * 4 * 3 * 2 * 1 * Rescue(0),由于程序在 n == 0 时 return ,此时 Rescue(0) = 0,那么最终结果就为120 。

因为递归式在调用自身下一层时使用了运算符相连,那么每次调用都都会使得运算符数量增多,,达到一定程度后,系统不得不使用栈进行数据保存和恢复。
如果每次递归都要运算一次所有运算符,那速度不仅极慢,还有可能导致栈溢出,导致程序奔溃。

2.尾递归

代码如下(示例):

package main
import "fmt"

func RescueTail(n int, a int) int {

	if n == 1 {
		return a
	}

	// 进入下一层
	// 例:RescueTail(5-1, 1 * 5)
	// 再下一层 此时 1 * 5 已计算完成
	// 例:RescueTail(4-1, 5 * 4)
	// 再下一层 此时 5 * 4 已计算完成
	// 例:RescueTail(3-1, 20 * 3)
	return RescueTail(n-1, a * n)
}


func main() {
	fmt.Println(RescueTail(5, 1))
}

尾递归从上述代码可以知道递归函数在调用自身后直接传回其值,而不对其再加运算,效率将会极大的提高。与递归相比尾递归将 a * n 在 return 时已经计算,那么 每次调用只需要判断一次运算符,而不用考虑重复调用的累赘。在上面代码中,RescueTail(5, 1)虽然会不断调用自身,但最终形态依然为 RescueTail(0, 120),此时最终形态与初态差距不大,且由于程序在 n == 0 时 return ,此时 return a,那么最终结果就也为120 。

尾递归函数,部分IDE将会识别并进行优化,为尾递归分配更少的堆栈,相比递归来说减少了很多不必要的内存占用与降低了堆栈溢出风险。由于初态与最终态的形态相差不大,程序的堆栈不会进行大量占用与内存消耗,相比递归来说风险与实用性都大大提高。


总结

通过对比递归与尾递归,我们可以很轻松了解在Golang中尾递归的优势,那么熟悉尾递归,尽量减少递归写法是我们很需要的事情。在学习之路不断地提高,是我们永远的目标。

希望这个博客能对你有所益处。我是轻王,我为自己代言。
  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猫轻王

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值