递归算法详解

递归

递归是编程中的一个重要概念,它允许函数在执行过程中调用自身。递归算法在数学和计算机科学中有广泛的应用。递归的基本思想是将复杂问题分解为更小的子问题,这些子问题在结构和逻辑上与原问题相似,可以通过重复调用自身来解决。

递归的步骤

1、假设递归函数已经写好

2、寻找递推关系

3、将递推关系的结构转换为递归体

4、将临界条件加入到递归体中(一定要加临界条件,某则陷入死循环,内存泄漏)

优缺点

递归的优点包括代码简洁、易于理解和阅读,以及能够处理复杂问题。

然而,递归也可能导致一些问题,如执行效率较低、占用的内存空间较多,以及可能存在无限递归的风险,导致栈溢出。为了防止无限递归,递归函数通常需要一个明确的终止条件!

简单易于理解的递归例子

求 1到任意数的和

function qiuHe(n) {
      if (n === 1) {
        return 1;
      }
      console.log('(n-1):', (n - 1), 'n:', n);
      return qiuHe(n - 1) + n;
    }

    console.log(qiuHe(10));

这是控制台输出结果,也就是递归的步骤

斐波那契数列

斐波那契数列来源于兔子繁殖问题,所以也叫兔子序列。

第一年有一对小兔子,一年后成年。成年的兔子又可以生出一对小兔子,如此循环往复,每年的兔子数就构成了一个斐波那契数列。

由于兔子无限繁殖,在计算第n年兔子数量时,n每增加1,运算量就成指数级增加,因此测试时填写n的值时请不要填入太大的值,防止计算机死机或卡顿!

function fib(n) {
      if (n == 0 || n == 1) {
        return 1;
      }
      return fib(n - 1) + fib(n - 2);
    }

    console.time("计时器1");
    console.log(fib(15));
    console.timeEnd("计时器1");
    console.time("计时器2");
    console.log(fib(20));
    console.timeEnd("计时器2");
    console.time("计时器3");
    console.log(fib(25));
    console.timeEnd("计时器3");

控制台输出

由输出结果可知,求第15年时兔子数量用了0.20ms,第20年用了0.25ms,第25年用了1.27ms。所需时间成指数级上升。

树状结构递归

 var node = [
      {
        id: 1,
        name: "1-1",
        children: [
          {
            id: 1111,
            name: "1-1-1",
          },
          {
            id: 2222,
            name: "1-1-2",
          },
          {
            id: 333,
            name: "1-1-3",
            children: [
              {
                id: 44444,
                name: "1-1-3-1",
              },
              {
                id: 44444,
                name: "1-1-3-2",
              },
            ],
          },
        ],
      },
      {
        id: 2,
        name: "1-2",
      },
    ];

    var arr = [];

    function getLeafkey(node) {
      node.forEach(function (item) {
        console.log(item.name);

        if (item.children) {
          getLeafkey(item.children);
        }
      });
    }

    getLeafkey(node);

控制台输出

数组扁平化

    var arr = [1, [11, 12, 13], [21, 22, 23, [241, 242, [2431, 2432]]]];

    var res = [];
    function flat(arr) {
      arr.forEach(function (item) {
        if (Array.isArray(item)) {
          flat(item);
        } else {
          res.push(item);
        }
      });
    }
    flat(arr);
    console.log(res);

控制台输出

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值