用一个猴子的例子理解递归

175 阅读2分钟

无论你是恨它的、爱它的还是恨了几年后又爱上它的,只要写代码,你都绕不开它,那就是递归。因此,准确而有趣的理解它,很重要。

递归需要解决的问题

猴子来到了龙宫要兵器,龙王说:这有一个大大的箱子,大箱子里面有各种小箱子,小箱子里面有可能有更小的箱子,可能箱子箱孙无穷尽也,这大大小小的箱子中,有一个箱子里放着一根开天辟地以来第一神兵,大圣你展示你的神通,找到它,就可以拿走它!

WechatIMG577.jpeg

WechatIMG576.jpeg

递归函数重要的两部分

编写递归函数时,必须告诉它何时停止递归。正因为如此,每个递归函数都有两部分:基线条件(base case)和递归条件(recursive case)。递归条件指的是函数调用自己,而基线条件则指的是函数不再调用自己,从而避免形成无限循环。

大圣要做的就是在找到神兵之前,检查每一个箱子,如果箱子里不是神兵(递归条件(recursive case)),继续检查当前箱子里的小箱子,如果当前箱子里是神兵(基线条件(base case)),则停下来。大圣毕竟是大圣,如果只有自己找,那和while循环这凡夫俗子(凡夫俗子很强大)有什么差别?所以,这只聪明的猴子每遇上一个箱子,就拔一根毫毛,召唤一只猴子来检查箱子(满足递归条件,调用自己),直到有一只猴子找到了神兵(满足基线条件,停止递归),停止拔毛。

WechatIMG578.jpeg

const recursive = (boxs) => {
    boxs.forEach(box => {
        if (box.type === "golden cudgel") {
            // 找到了神兵
            console.log('found the golden cudgel');
        } else {
            // 召唤一只猴子,继续检查箱子
            recursive(box.children);
        }
    });
}

用while循环解决大圣的问题

“如果使用循环,程序的性能可能更高;如果使用递归,程序可能更容易理解。如何选择要看什么对你来说更重要。”

  1. 把东海龙王给的大箱子里的东西都拿出来,如果没找到神兵,把这些箱子组成一个箱子堆。
  2. 只要箱子堆有箱子,从箱子堆中取出一个箱子,找里面的东西。
  3. 如果是箱子,就将其放在箱子堆中,回头再查找。
  4. 如果是神兵,就抢走,一堆箱子(已检查的,未检查的)留给老龙王。

前端小学僧对递归学习的一点粗浅的借鉴和解释,多谢大家交流指正。

卡牌游戏时间

如果英雄杀有孙悟空这个英雄,技能会是什么呢?