尾递归

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

 

以上是关于尾递归的主要内容,如果未能解决你的问题,请参考以下文章

尾递归优化

如何看待以及理解Python的这种尾递归优化

尾递归=递归+迭代?

尾递归

JavaScript函数尾调用与尾递归

尾递归,