尾递归
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了尾递归相关的知识,希望对你有一定的参考价值。
前段时间无意间看到了老赵写的‘尾递归’,不禁觉得好神奇,当时看的时候好像是理解了,也照着写了代码;
可是过一段时间想起来‘尾递归’,却想不起该怎么写;
今天带着思考来写一遍!
问题:一个100层阶梯,每次可走1-3层,求登顶有多少种走法;
分析:既然每次只能走1-3层,那么走到100层的前一层,只能是97或98或99,走到100层的问题就分解成了走到97,98或99的走法之和
最简单直接的递归写法:
public static decimal Recursion(int n)
{
if (n < 4)
switch (n)
{
case 1: return 1;
case 2: return 2;
case 3: return 4;
}
return Recursion(--n) + Recursion(n - 1) + Recursion(n - 2);
}
可是这种递归的写法是非常消耗资源的,于是需要改写为不这么消耗资源‘尾递归’,
直接改为尾递归比较困难,想起来就头晕,先写成循环:
public static decimal ForCycle(int n)
{
decimal acc1 = 1, acc2 = 2, acc3 = 4, temp;
if (n < 4)
switch (n)
{
case 1: return 1;
case 2: return 2;
case 3: return 4;
}
while (n-- > 3)
{
temp = acc1;
acc1 = acc2;
acc2 = acc3;
acc3 = temp + acc1 + acc2;
}
return acc3;
}
有了这个循环的写法,尾递归就很好写出来了:
public static decimal RecursionTail(int n, decimal acc1, decimal acc2, decimal acc3)
{
if (n < 4)
return acc3;
return RecursionTail(--n, acc2, acc3, acc1 + acc2 + acc3);
}
public static decimal RecursionTailFace(int n)
{
decimal acc1 = 1, acc2 = 2, acc3 = 4;
if (n < 4)
switch (n)
{
case 1: return acc1;
case 2: return acc2;
case 3: return acc3;
}
return RecursionTail(--n, acc2, acc3, acc1 + acc2 + acc3);
}
这里不难看出,尾递归其实就是循环里面 while的另一种形式;
总结:尾递归和循环好像是一个东西,不同写法而已,个人觉得重点在于循环的while那里,while写出来了就好办了;
最后:在本例中,while (n-- > 3),为什么是3,
其实这个3可以理解为一个节点,在它之前,直接返回结果就好,在它之后就需要计算:比如n=4时,需要累加一次,n=5需要累加两次,所以这里就是3
以上是关于尾递归的主要内容,如果未能解决你的问题,请参考以下文章