函数——递归

Posted davina123

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了函数——递归相关的知识,希望对你有一定的参考价值。

  递归就是函数直接或者是间接的调用自己,相当于循环,使用时必需要有一个跳出条件,否则会进入死循环。它是栈的存取方式,先进后出,后进先出。

  主要用于循环,如阶乘函数、幂函数和斐波那契数列。

    <script>
        function fn(n) {
            if (n == 1) {
                return n;
            }
            return fn(n - 1) + n;
        }
        console.log(fn(5));  //15
    </script>

  以下为分析过程:

    <script>
        //分析:
        n = 5
        function fn(5) {
            if (5 === 1) {        //不满足
                return n;
            }
            return fn(4) + 5;    //10+5=15
        }

        n = 4
        function fn(4) {
            if (4 === 1) {        //不满足
                return n;
            }
            return fn(3) + 4;    //6+4=10
        }

        n = 3
        function fn(3) {
            if (3 === 1) {        //不满足
                return n;
            }
            return fn(2) + 3;    //3+3=6
        }

        n = 2
        function fn(2) {
            if (2 === 1) {        //不满足
                return n;
            }
            return fn(1) + 2;    //1+2=3
        }

        n = 1
        function fn(1) {
            if (1 === 1) {        //满足
                return 1;
            }
            return fn(1) + 2;
        }
    </script>

  尾递归:尾递归是递归的一种优化,函数的最后一步是调用另一个函数,尾递归函数的每子一层函数不再需要使用父一层的函数执行完毕就会销毁栈记录,避免了内存溢出,节省了内存空间,只走一次,性能很高。

    <script>
        function fn(n, result) {
            return (n === 1) ? result : fn(n - 1, n + result);
        }
        console.log(fn(5, 1)); //15
    </script>

  分析过程如下:

    <script>
        //n=5,result=1;
        function fn(5,1) {
            return (5 === 1) ? result : fn(4, 6);
        }
        //n=4,result=6;
        function fn(4,6) {
            return (4 === 1) ? result : fn(3, 10);
        }
        //n=3,result=10;
        function fn(3,10) {
            return (3 === 1) ? result : fn(2, 13);
        }
        //n=2,result=13;
        function fn(2,13) {
            return (2 === 1) ? result : fn(1, 15);
        }
        //n=1,result=15;
        function fn(1,15) {
            return (1 === 1) ? 15 : fn(1, 15);
        }
    </script>

  递归的运用:深拷贝(deepClone)

   浅拷贝在引用类型的时候,它只是复制了地址值,实际上还是指向同一堆内存中的数据而深拷贝则是重新创建了一个相同的数据,二者的堆内存的地址值是不一样的。深拷贝中修改赋值后变量的数据不会对之前的数据产生影响。递归可以用于深拷贝。

 <script>
        const deepCopy = obj => {
            if (typeof obj !== object) {
                return;
            }
            const newObj = obj instanceof Array ? [] : {};
            for (let key in obj) {
                if (obj.hasOwnProperty(key)) {
                    newObj[key] = typeof obj[key] === object ? deepCopy(obj[key]) : obj[key];
                }
            }
            return newObj;
        }
        const obj1 = {
            a: 10,
            b: function () {
                console.log(1);
            },
            c: [1, 2, 3],
            d: {
                f: [2, { a: 20 }]
            },
            e: {
                h: true
            }
        };

        const obj2 = deepCopy(obj1);
        console.log(obj2);

        obj2.b = function () {
            console.log(2);
        };
        obj2.b();    //2
        obj1.b();    //1

        obj2.e = [123];
        console.log(obj1.e, obj2.e);    //{h: true} [123]
    </script>

 

 

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

vue递归组件的一些理解

哈斯克尔。我很困惑这个代码片段是如何工作的

如何在自定义PyYAML构造函数中处理递归?

JavaSE 方法的使用

JavaScript - 代码片段,Snippets,Gist

Java基础之方法的调用重载以及简单的递归