目录

1 递归从盒子中找钥匙开始

Stack Overflow:Recursion or Iteration?

2 基线条件和递归条件

3 栈

4 小结

5 试例代码

Python

C

C#

Java

JS

Matlab


1 递归从盒子中找钥匙开始

假设你在祖母的阁楼中翻箱倒柜,发现了一个上锁的神秘手提箱。

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

Loops may achieve a performance gain for your program. Recursion may achieve a performance gain for your programmer. Choose which is more important in your situation!

Stack Overflow:Recursion or Iteration?

Comparing recursion to iteration is like comparing a phillips head screwdriver to a flat head screwdriver. For the most part you could remove any phillips head screw with a flat head, but it would just be easier if you used the screwdriver designed for that screw right?

Some algorithms just lend themselves to recursion because of the way they are designed (Fibonacci sequences, traversing a tree like structure, etc.). Recursion makes the algorithm more succinct and easier to understand (therefore shareable and reusable).

Also, some recursive algorithms use "Lazy Evaluation" which makes them more efficient than their iterative brothers. This means that they only do the expensive calculations at the time they are needed rather than each time the loop runs.

That should be enough to get you started. I'll dig up some articles and examples for you too.

Link 1: Haskel vs PHP (Recursion vs Iteration)

Here is an example where the programmer had to process a large data set using PHP. He shows how easy it would have been to deal with in Haskel using recursion, but since PHP had no easy way to accomplish the same method, he was forced to use iteration to get the result.

http://blog.webspecies.co.uk/2011-05-31/lazy-evaluation-with-php.html

Link 2: Mastering Recursion

Most of recursion's bad reputation comes from the high costs and inefficiency in imperative languages. The author of this article talks about how to optimize recursive algorithms to make them faster and more efficient. He also goes over how to convert a traditional loop into a recursive function and the benefits of using tail-end recursion. His closing words really summed up some of my key points I think:

"recursive programming gives the programmer a better way of organizing code in a way that is both maintainable and logically consistent."

Mastering recursive programming – IBM Developer

Link 3: Is recursion ever faster than looping? (Answer)

Here is a link to an answer for a stackoverflow question that is similar to yours. The author points out that a lot of the benchmarks associated with either recursing or looping are verylanguage specific. Imperative languages are typically faster using a loop and slower with recursion and vice-versa for functional languages. I guess the main point to take from this link is that it is very difficult to answer the question in a language agnostic / situation blind sense.

Is recursion ever faster than looping?

2 基线条件和递归条件

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

def countdown(i):print(i)if i <= 0:returnelse:countdown(i-1)countdown(5)

3 栈

调用另一个函数时,当前函数暂停并处于未完成状态。该函数的所有变量的值都还在内存中。

def countdown(i):# print(i)if i == 1:return 1else:return i*countdown(i-1)print(countdown(3))

注意,每个fact调用都有自己的x变量。在一个函数调用中不能访问另一个的x变量。

4 小结

 递归指的是调用自己的函数。
 每个递归函数都有两个条件:基线条件和递归条件。
 栈有两种操作:压入和弹出。
 所有函数调用都进入调用栈。
 调用栈可能很长,这将占用大量的内存。

5 试例代码

Python

def greet2(name):print("how are you, ", name, "?")def bye():print("ok bye!")def greet(name):print("hello, ", name, "!")greet2(name)print("getting ready to say bye...")bye()greet("adit")
def fact(x):if x == 1:return 1else:return x * fact(x-1)print(fact(5))

C

#include <stdio.h>void countdown(int i) {printf("%d\n", i);// base caseif (i <= 0)return;//recursive caseelsecountdown(i - 1);
}int main(void) {countdown(5);return 0;
}
#include <stdio.h>void greet2(char *name) {printf("how are you, %s?\n", name);
}void bye() {printf("ok bye!\n");
}void greet(char *name) {printf("hello, %s!\n", name);greet2(name);printf("getting ready to say bye...\n");bye();
}int main(void) {greet("adit");return 0;
}
#include <stdio.h>int fact(int x) {if (x == 1)return 1;elsereturn x * fact(x - 1);
}int main(void) {printf("%d", fact(5));return 0;
}

C#

using System;namespace ConsoleApplication
{public class Program{public static void Main(string[] args){Console.WriteLine(Fact(5));}private static int Fact(int x){if (x <= 1) return 1;return x * Fact(x - 1);}}
}

Java


public class Countdown {private static void countdown(int i) {System.out.println(i);// base caseif (i <= 0) {return;} else {countdown(i - 1);}}public static void main(String[] args) {countdown(5);}
}
public class Factorial {private static int fact(int x) {if (x == 1) {return 1;} else {return x * fact(x - 1);}}public static void main(String[] args) {System.out.println(fact(5));}
}

JS


function countdown(i) {console.log(i);// base caseif (i <= 0) {return;} else {countdown(i-1);}
}countdown(5);
function greet2(name) {console.log('how are you, ' + name + '?');
}function bye() {console.log('ok bye!');
}function greet(name) {console.log('hello, ' + name + '!');greet2(name);console.log('getting ready to say bye...');bye();
}greet('adit');
function fact(x) {if (x === 1) {return 1;} else {return x * fact(x-1);}
}console.log(fact(5));

Matlab

function f=factial(n)
if n==0
f=10;
elseif n>=1
f=n*factial(n-1);
end

《图解算法》学习笔记之递归相关推荐

  1. 图解算法学习笔记(三):递归

    本章内容: 学习递归:如何将问题分解成基线条件和递归条件.     1) 每个递归函数都有两部分:基线条件(base case)和递归条件(recursive base).例如:打印3...2...1 ...

  2. 图解算法学习笔记(四):快速排序

    目录 1) 示例1: 2)快速排序 3) 再谈大O表示法 4)小结 本章内容:学习分而治之,快速排序 1) 示例1: 假设你是农场主,有一小块土地,你要将这块地均匀分成方块,且分出的方块尽可能大.如何 ...

  3. 图解算法学习笔记(九):动态规划

    目录 (1)背包问题 (2)最长公共子串 (3)小结 本章内容: 学习动态规划,它将问题分成小问题,并先着手解决这些小问题. 学习如何设计问题的动态规划解决方案. (1)背包问题 我们再看第八章的背包 ...

  4. 图解算法学习笔记(八):贪婪算法

    目录 (1)背包问题 (2)集合覆盖问题 (3)NP完全问题 (4)小结 本章内容: 学习如何处理没有快速算法的问题(NP完全问题). 学习近似算法,使用它们找到NP问题的近似解. 学习贪婪策略. ( ...

  5. 图解算法学习笔记(六):广度优先搜索

    目录 1)图简介 2)图是什么 3)广度优先搜索 4)实现图 5)实现算法 6)小结 本章内容; 学习使用新的数据结构图来建立网络模型: 学习广度优先搜索: 学习有向图和无向图: 学习拓扑排序,这种排 ...

  6. 图解算法学习笔记(一): 算法简介

    本章内容: 编写第一种查找算法--二分查找. 学习如何谈论算法的运行时间--大O表示法. 1) 算法是一组完成任务的指令,任何代码片段都可视为算法. 2)二分查找:一种查找算法,其输入是一个有序的元素 ...

  7. 图解算法学习笔记(目录)

    今天遇到一本好书,如下,书很薄,不到200页,有将近400张图片,算法介绍的很有趣.这也是我读的第三本袁国忠先生翻译的书,向两位致敬. 目录大致如下; 第1章:二分查找和大O表示法: 第2章:数组和链 ...

  8. 图解算法学习笔记(七):狄克斯特拉算法

    目录 1)使用狄克斯特拉算法 2)术语 3)实现 4)小结 本章内容; 介绍加权图,提高或降低某些边的权重: 介绍狄克斯特拉算法,找出加权图中前往X的最短路径: 介绍图中的环,它导致狄克斯特拉算法不管 ...

  9. 图解算法学习笔记(五):散列表

    目录 1)示例1: 2)散列函数 3)应用案例 4)冲突 5)性能 6)小结 本章内容: 学习散列表,最有用的数据结构之一. 学习散列表的内部机制:实现.冲突和散列函数. 1)示例1: 假设你在一家杂 ...

  10. 图解算法学习笔记(二): 选择排序

    目录 1)数组和链表: 2)选择排序算法: 3)小结 本章内容: 两种基本数据结构:数组和链表: 选择排序算法: 1)数组和链表: 数组是连续的内存单元,链表可以不连续: 链表存储单元如图所示,每一个 ...

最新文章

  1. 使用snmp对DNS服务器进行图形化监控
  2. sql 精读(三) 标准 SQL 中的编号函数示例
  3. javaFX的控制台实现
  4. SimGAN-Captcha代码阅读与复现
  5. 易格斯拖链选型手册_拖链相关知识
  6. Maven把一个Application转换成WebProject
  7. C++对象内存布局--④VS编译器--单个虚拟继承
  8. 任务、进程、线程之间的区别
  9. DEKR 解构式关键点回归(一):算法思想与原理
  10. java语言实现任何一种排序_请用java语言编写排序程序。
  11. 哈哈,代码比较工具,好像就这5款比较顺手~~~
  12. 直流双闭环pwm调速系统matlab仿真,基于Matlab的双闭环PWM直流调速虚拟实验系统
  13. doc 问卷调查模板表_调查问卷模板.doc
  14. 在FPGA中,同步信号、异步信号和亚稳态的理解
  15. 水晶易表 oracle,水晶易表调用C#的WebService,返回数据集合的应用分析
  16. 中国足球深度剖析之五,破除周期性怪圈
  17. php微信h5支付demo,微信h5支付 demo-HTML5微信支付DEMO下载 最新版--pc6下载站
  18. linux 使用scp命令,scp命令详解(全)
  19. HP elitebook 735 g5 笔记本电脑升级BIOS驱动后Type-C无法扩展显示屏的解决方案
  20. 嵌入式系统硬件构成-嵌入式系统硬件体系结构

热门文章

  1. C# NPOI NPOI加载 Excel加载 Excel读取 Excel写入 Excel修改 保证完整能用
  2. 微型计算机系统三层结构,微型计算机系统结构图.doc
  3. MFC 之序列化 serialize 和CArchive
  4. 哪些大学有计算机动漫专业,计算机专业考研有哪些值得推荐的院校?
  5. python 微信爬虫_PythonWchatScrapy
  6. ps打开闪退_Photoshop2020安装教程,会安装软件是学ps的前提
  7. linux内核多个补丁,一个令人惊叹的Linux内核补丁
  8. gdb 命令_16. 如何使用 GDB 调试 Go 程序?
  9. 联想计算机phoenix award bios,phoenix-Award BIOS
  10. 微服务架构的链路追踪和故障快速排查zipkin(微服务治理)