无论你是恨它的、爱它的还是恨了几年后又爱上它的,只要写代码,你都绕不开它,那就是递归。因此,准确而有趣的理解它,很重要。
递归需要解决的问题
猴子来到了龙宫要兵器,龙王说:这有一个大大的箱子,大箱子里面有各种小箱子,小箱子里面有可能有更小的箱子,可能箱子箱孙无穷尽也,这大大小小的箱子中,有一个箱子里放着一根开天辟地以来第一神兵,大圣你展示你的神通,找到它,就可以拿走它!
递归函数重要的两部分
编写递归函数时,必须告诉它何时停止递归。正因为如此,每个递归函数都有两部分:基线条件(base case)和递归条件(recursive case)。递归条件指的是函数调用自己,而基线条件则指的是函数不再调用自己,从而避免形成无限循环。
大圣要做的就是在找到神兵之前,检查每一个箱子,如果箱子里不是神兵(递归条件(recursive case)),继续检查当前箱子里的小箱子,如果当前箱子里是神兵(基线条件(base case)),则停下来。大圣毕竟是大圣,如果只有自己找,那和while循环这凡夫俗子(凡夫俗子很强大)有什么差别?所以,这只聪明的猴子每遇上一个箱子,就拔一根毫毛,召唤一只猴子来检查箱子(满足递归条件,调用自己),直到有一只猴子找到了神兵(满足基线条件,停止递归),停止拔毛。
const recursive = (boxs) => {
boxs.forEach(box => {
if (box.type === "golden cudgel") {
// 找到了神兵
console.log('found the golden cudgel');
} else {
// 召唤一只猴子,继续检查箱子
recursive(box.children);
}
});
}
用while循环解决大圣的问题
“如果使用循环,程序的性能可能更高;如果使用递归,程序可能更容易理解。如何选择要看什么对你来说更重要。”
- 把东海龙王给的大箱子里的东西都拿出来,如果没找到神兵,把这些箱子组成一个箱子堆。
- 只要箱子堆有箱子,从箱子堆中取出一个箱子,找里面的东西。
- 如果是箱子,就将其放在箱子堆中,回头再查找。
- 如果是神兵,就抢走,一堆箱子(已检查的,未检查的)留给老龙王。
前端小学僧对递归学习的一点粗浅的借鉴和解释,多谢大家交流指正。
卡牌游戏时间
如果英雄杀有孙悟空这个英雄,技能会是什么呢?