JavaScript之递归

递归基础
  • 什么是递归?
    在JavaScript程序中,函数直接或间接调用自己。通过某个条件判断跳出结构,得出结果。递归的本质就是一个循环
  • 引用之前在知乎看到的一个对递归的理解。从前有座山,山里有个庙,庙里有个老和尚在给小和尚讲故事,讲的是从前有座山,山里有个庙,庙里有个老和尚在给小和尚讲故事,讲的是从前有座山。。。
    或者
for(let i = 0; i < 1; i--) {
    console.log(i);
}

这里可以看出是一个循环了吧,这是一个死循环,没有终止条件。

  • 也可以看下面一个例子:
function fn() {
    console.log(1);
    fn(); // 递归,自己调用自己
}
fn() // 没有终止条件,这个递归就是一个死循环。
// 1
// 1
// 1
// ...
  • 看到这应该是基本明白是什么意思了,那看一下下面的递减:
function cut(n) {
    if(n === 0) return;
    console.log(n);
    cut(n - 1);
}
cut(5);
// 5
// 4
// 3
// 2
// 1
  • 看出了什么,是不是多了一个判断条件?if(n === 0) return;这是避免进入死循环,所以使用递归的时候,一定要加上临界条件(或者说是边界条件),否则就会陷入死循环。
    再比如让你求一个1-100的和,你是不是会这样写:
var sum = 0;
for(let i = 1; i <= 100; i++) {
    sum += i;
}
console.log(sum) // 5050

那么使用递归呢,该如何去计算1-100的和?
用递归求1-100的和,即sum(100),我们可以列出公式:

var result = sum(100);
var result = sum(99) + 100;
var result = sum(98) + 100;
var result = sum(97) + 100;
var result = sum(96) + 100;
...

然后我们是不是可以由以上的公式得出一下结果:

var result = sum(n-1) + n;

转成递归结构是不是

function sum(n) {
    return sum(n-1) + n;
}

但是按我们上面所说,使用递归的时候,一定要加上临界条件,否则就会陷入死循环。
那在计算1-100的和的临界条件是什么呢?
我们可以这样算:
100的时候转换为求99
99的时候转换为求98
98的时候转换为求97
97的时候转换为求96
...
2的时候转换为求1
1的时候转换为求
所以,这里我们就得加上临界条件啦,即sum(1) = 1;
那么,递归函数是不是:

function sum(n) {
    if(n === 1) return 1;
    return sum(n-1) + n;
}
sum(100)
// 5050

记得还有一个arguments.callee方法,但是用的比较少了,可以这样

function sum(n) {
    if(n === 1) {
        return n;
    }else {
        return n + arguments.callee(n - 1);
    }
}
sum(100)
// 5050
  • 假设让你分别求奇数偶数的和是多少呢?

比如求奇数和
是不是可以举例子,如1、3、5、7、9、11、13、15、17、19...
第一项是1,第二项是3,第三项是5
那是不是设fn(n)为第几项(第n项),即sum(n)为前n项之和?
那就可以得出公式:

fn(n) = fn(n-1) + 2;
sum(n) = fn(n) + sum(n - 1);

那么这样是不是可以猜出递归结构了?

function fn(n) {
    return fn(n - 1) + 2;
}
function sum(n) {
    return fn(n) + sum(n - 1);
}

到了这里,我们是不是忘记了很重要的一点,忘记加上临界条件了,那么他们的临界条件是什么呢?
我们知道,按上面举的例子1、3、5、7、9、11、13、15、17、19...
fn(0)是不是1 ?
fn(1)是不是3 ?
fn(2)是不是5 ?
...
那么最小的是不是fn(0) ?,在正整数中,最小的奇数是不是1,所以这个fn的临界条件就是fn(0) = 1;
既然fn(0)的值都是1了,那sum(0)是不是也是1,所以
临界条件
fn(0) = 1;
sum(0) = 1;
那么就可以得出

function fn(n) {
    if(n === 0) return 1;
    return fn(n - 1) + 2;
}
function sum(n) {
    if(n === 0) return 1;
    return fn(n) + sum(n-1);
}
// 计算100以内所有奇数和, 100以内奇数有50个
sum(49) // 0-49
// 2500

那么求偶数和是不是更简单了,只需要改变临界条件就行了。
比如,举个例子,2、4、6、8、10、12、14、16、18、20...
fn(0)是不是2
fn(1)是不是4
fn(2)是不是6
fn(3)是不是8
...
正整数中,最小的偶数是不是2?,所以fn(0)就是2,对应的sum(0)是不是也是2
得出的临界条件是不是
fn(0) = 2;
sum(0) = 2;
那么递归函数是不是

function fn(n) {
    if(n === 0) return 2;
    return fn(n - 1) + 2;
}
function sum(n) {
    if(n === 0) return 2;
    return fn(n) + sum(n-1);
}
// 计算100以内所有偶数和, 100以内偶数也是50个
sum(49) // 0-49
// 2550

递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量 。递归在很多语言中都很常见,合理的使用,可以帮助我们解决很多问题。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,753评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,668评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,090评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,010评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,054评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,806评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,484评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,380评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,873评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,021评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,158评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,838评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,499评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,044评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,159评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,449评论 3 374
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,136评论 2 356