Tail recursion

递归:
一个函数中不断调用自己的这么一种调用形式。
递归的资源消耗是发生在栈中,在调用函数时候,通常需要保存相应的资源,比如参数,返回地址,局部变量等。那么进行大量的递归,就会造成栈的溢出。在进行递归的时候,本身递归函数的状态,没有完全执行完毕,需要借助于下一个状态来完成,那么上一个状态必然要进行保存,这样就导致了大量的中间过程,并在回溯递归的时候使用,得到最后结果。

阶乘函数:

int factorial(int n)
{
	if(n==0)
		return 1;
	else 
		return n*factorial(n-1);
}

在上述的函数中,返回的值并不是一个完全独立的状态,而需要保存n这样一种额外需维护的变量,每层递归都需要这样一个变量,那么在下次调用的时候,就会重新创建新的栈帧来进行保存。每次都是这样。所以对于大数而言,就可能溢出了。

尾递归:
本质就是不产生出中间过程,将中间过程作为函数的参数,传入到下次调用中去。比如上面阶乘函数,使用尾递归设计后。

int factorial_tailcursion(int n,int acc)
{
	if(n==0)
		return acc;
	else 
		return factorial_tailcursion(n-1,acc*n);
}

在调用的时候 factorial_tailcursion(n,1) 需要一个初始累计器acc=1。没有产生中间过程,中间变量都通过参数传递给下一次调用,从而节省了栈的开销。因为对于某些编译器而言,会自动识别到这一动作,并且认为每次调用过程都是独立的,那么就不需要每次都开辟新的 栈帧来保存当前值,而是直接就地覆盖调之前的栈。那么其空间复杂度将为O(1)。这就是尾递归的本质。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值