2018-03-08 迭代与递归

昨天在群里看到有群友在讨论迭代与递归的区别,仔细检索了下大脑,好像真的记不清了,有些惭愧...。有空搜索下了,终于知道了它们的区别。以下概念内容参考于铭毅天下的博文

递归的基本概念:程序调用自身的编程技巧称为递归,是函数自己调用自己。

一个函数在其定义中直接或间接调用自身的一种方法。它通常把一个大型的复杂的问题转化为一个与原问题相似的规模较小的问题来解决,可以极大的减少代码量。递归的能力在于用有限的语句来定义对象的无限集合。

使用递归时需要注意的两点:

1.递归就是在过程或函数里面调用自身;

2.在使用递归时,必须有一个明确的递归结束条件,称为递归出口,从而避免方法出现死循环。

使用递归能解决一些经典问题,例如,斐波那契数列为:0,1,1,2,3,5...,从n到m的阶乘等。

迭代:利用变量的原值推算出变量的一个新值,通过重复一定的算法,达到想要的目的。迭代就是A不停的调用B,得到结果。

迭代一般的代码形式是循环结构,for循环,while循环等。而递归的代码结构是选择结构。

递归的优点是:代码量极小,简洁,可读性好;缺点是:递归调用函数,浪费函数栈空间,并且递归太深容易造成堆栈的溢出。

迭代的优点有:迭代效率高,没有额外的空间消耗;缺点是:代码不简洁,编写复杂问题时代码臃肿。

代码技术不能只看理论,光说不练假把式。所以我写了几段代码来验证下,纸上说的与实际代码效果是否相符。

先来看看迭代的方式


- (void)test1 {

    //使用迭代的方法,也就是使用for循环

    CFAbsoluteTime startTime = CFAbsoluteTimeGetCurrent();

    NSUIntegersum = 0;

    for(int i = 0; i <= count; i++) {

        sum = sum + i;

    }

    CFAbsoluteTime endTime = CFAbsoluteTimeGetCurrent();

    NSLog(@"sum=%ld, time cost:%f ms", sum, (endTime - startTime)*1000);

}

这里的count我依次设置了三次值10000,100000,1000000,每次也连续执行3次,看其平均值。
当count为10000时,代码连续执行3次,打印如下

2018-03-08 15:11:24.833246+0800 Test[947:45941] sum=50005000, time cost:0.038028 ms
2018-03-08 15:11:25.945530+0800 Test[947:45941] sum=50005000, time cost:0.036001 ms
2018-03-08 15:11:26.962520+0800 Test[947:45941] sum=50005000, time cost:0.036001 ms

我们再来看看递归的实现方式

- (void)test2 {
    //使用递归的方法
    CFAbsoluteTime startTime = CFAbsoluteTimeGetCurrent();
    
    NSUInteger sum = [self addNumberToN:count];
    
    CFAbsoluteTime endTime = CFAbsoluteTimeGetCurrent();
    NSLog(@"sum=%ld, time cost:%f ms", sum, (endTime - startTime)*1000);
}

- (NSUInteger )addNumberToN:(NSUInteger )n {
    if (n == 0) {
        return 0;
    }
    else {
        return n + [self addNumberToN:(n-1)];
    }
}

当count为10000时,代码连续执行3次,打印如下

2018-03-08 15:16:20.969425+0800 Test[963:47741] sum=50005000, time cost:0.447035 ms
2018-03-08 15:16:21.898042+0800 Test[963:47741] sum=50005000, time cost:0.156045 ms
2018-03-08 15:16:23.362979+0800 Test[963:47741] sum=50005000, time cost:0.183940 ms

从上面可以看出,计算从1到10000的累加之和,循环迭代的时间消耗比方法递归调用要快一个数量级,并且循环迭代多次调用的时间消耗相对比较平均,稳定性高。方法递归的情况下,多次调用,第一次耗时最长,之后趋于平均。

之后,我继续尝试了count的值为100000,1000000的情况。
循环迭代的打印如下
count=100000

2018-03-08 15:27:27.733217+0800 Test[989:51140] sum=5000050000, time cost:0.359058 ms
2018-03-08 15:27:28.909848+0800 Test[989:51140] sum=5000050000, time cost:0.359058 ms
2018-03-08 15:27:30.006191+0800 Test[989:51140] sum=5000050000, time cost:0.316978 ms

count=1000000

2018-03-08 15:28:48.569061+0800 Test[1006:51953] sum=500000500000, time cost:3.015041 ms
2018-03-08 15:28:49.553860+0800 Test[1006:51953] sum=500000500000, time cost:3.122926 ms
2018-03-08 15:28:50.474250+0800 Test[1006:51953] sum=500000500000, time cost:3.030062 ms

方法递归的打印如下
count=100000

2018-03-08 15:30:46.876513+0800 Test[1028:53026] sum=5000050000, time cost:4.575968 ms
2018-03-08 15:30:48.066177+0800 Test[1028:53026] sum=5000050000, time cost:1.581073 ms
2018-03-08 15:30:49.620131+0800 Test[1028:53026] sum=5000050000, time cost:2.056003 ms

count=1000000
运行崩溃,如下图


屏幕快照 2018-03-07 下午5.18.45.png

可以看到,app的方法栈堆积到了13万多次,应该是达到iOS系统允许app方法栈数量的极限,app崩溃。

以上可以看出,虽然递归代码简洁、可读性好,但是迭代效率高,空间消耗小,时间消耗也比递归快一个数量级。因此,在我们的日常开发中还是能用迭代就不用递归。

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

推荐阅读更多精彩内容