程序员必备的基本算法:递归详解
什么是递归?
递归,在计算机科学中是指一种通过重复将问题分解为同类的子问题而解决问题的方法。简单来说,递归表现为函数调用函数本身。在知乎看到一个比喻递归的例子,个人觉得非常形象,大家看一下:
❝
递归最恰当的比喻,就是查词典。我们使用的词典,本身就是递归,为了解释一个词,需要使用更多的词。当你查一个词,发现这个词的解释中某个词仍然不懂,于是你开始查这第二个词,可惜,第二个词里仍然有不懂的词,于是查第三个词,这样查下去,直到有一个词的解释是你完全能看懂的,那么递归走到了尽头,然后你开始后退,逐个明白之前查过的每一个词,最终,你明白了最开始那个词的意思。
❞
来试试水,看一个递归的代码例子吧,如下:
public int sum(int n) {if (n <= 1) {return 1;} return sum(n - 1) + n;
}
递归的特点
实际上,递归有两个显著的特征,终止条件和自身调用:
- 自身调用:原问题可以分解为子问题,子问题和原问题的求解方法是一致的,即都是调用自身的同一个函数。
- 终止条件:递归必须有一个终止的条件,即不能无限循环地调用本身。
结合以上demo代码例子,看下递归的特点:
递归与栈的关系
其实,递归的过程,可以理解为出入栈的过程的,这个比喻呢,只是为了方便读者朋友更好理解递归哈。以上代码例子计算sum(n=3)的出入栈图如下:
为了更容易理解一些,我们来看一下 函数sum(n=5)的递归执行过程,如下:
- 计算sum(5)时,先sum(5)入栈,然后原问题sum(5)拆分为子问题sum(4),再入栈,直到终止条件sum(n=1)=1,就开始出栈。
- sum(1)出栈后,sum(2)开始出栈,接着sum(3)。
- 最后呢,sum(1)就是后进先出,sum(5)是先进后出,因此递归过程可以理解为栈出入过程啦~
递归的经典应用场景
哪些问题我们可以考虑使用递归来解决呢?即递归的应用场景一般有哪些呢?
- 阶乘问题
- 二叉树深度
- 汉诺塔问题
- 斐波那契数列
- 快速排序、归并排序(分治算法也使用递归实现)
- 遍历文件,解析xml文件
递归解题思路
解决递归问题一般就三步曲,分别是:
- 第一步,定义函数功能
- 第二步,寻找递归终止条件
- 第二步,递推函数的等价关系式
这个递归解题三板斧理解起来有点抽象,我们拿阶乘递归例子来喵喵吧~
1.定义函数功能
定义函数功能,就是说,你这个函数是干嘛的,做什么事情,换句话说,你要知道递归原问题是什么呀?比如你需要解决阶乘问题,定义的函数功能就是n的阶乘,如下:
//n的阶乘(n为大于0的自然数)
int factorial (int n){}
2.寻找递归终止条件
递归的一个典型特征就是必须有一个终止的条件,即不能无限循环地调用本身。所以,用递归思路去解决问题的时候,就需要寻找递归终止条件是什么。比如阶乘问题,当n=1的时候,不用再往下递归了,可以跳出循环啦,n=1就可以作为递归的终止条件,如下:
//n的阶乘(n为大于0的自然数)
int factorial (int n){if(n==1){return 1;}
}
3.递推函数的等价关系式
递归的「本义」,就是原问题可以拆为同类且更容易解决的子问题,即「原问题和子问题都可以用同一个函数关系表示。递推函数的等价关系式,这个步骤就等价于寻找原问题与子问题的关系,如何用一个公式把这个函数表达清楚」。阶乘的公式就可以表示为 f(n) = n * f(n-1), 因此,阶乘的递归程序代码就可以写成这样,如下:
int factorial (int n){if(n==1){return 1;}return n * factorial(n-1);
}
「注意啦」,不是所有递推函数的等价关系都像阶乘这么简单,一下子就能推导出来。需要我们多接触,多积累,多思考,多练习递归题目滴~
程序员必备的基本算法:递归详解相关推荐
- 好程序员技术分析JavaScript闭包特性详解
为什么80%的码农都做不了架构师?>>> 好程序员技术分析JavaScript闭包特性详解,今天来总结一下js闭包的那些事,以及遇到的坑和解决方法,希望对你有所帮助. 是的,没 ...
- 程序员新动向!大龄困惑详解!
有一批网易,搜狗,华为等知名互联网公司老员工站出来吐槽,说35岁之后的处境多么尴尬,尤其大数据.人工智能方向,如果资历不够.技术一般一般,每天在公司时刻提心吊胆,生怕被裁员. 1 为何会出现这种现象? ...
- 求n的阶乘的算法框图_当代程序员必备技能(算法)之:递归详解 - Java斗帝之路...
前言 递归是一种非常重要的算法思想,无论你是前端开发,还是后端开发,都需要掌握它.在日常工作中,统计文件夹大小,解析xml文件等等,都需要用到递归算法.它太基础太重要了,这也是为什么面试的时候,面试官 ...
- Android程序员必备!海量算法高频面试题精编解析,真香
前言 这里是我整理的2019年至2021年期间通过各个渠道花时间专门整理的面试题,其中面试重点和难点都有详细解析,重点讲的是Android各方面的专题讲解包括Java小部分的技术讲解.这些题目有点技术 ...
- 黑马程序员——多线程的实现(2+1)详解
------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 方法1:继承Thread类 继承Thread类,重写run方法,把需要被线程执行的代码写到run ...
- 程序员必备算法,排列组合
还记得排列组合吗? 在高中的时候最常接触的莫过于排列组合了,毕竟高考必考的嘛.我们先来回忆下这两个的公式是啥: 排列组合公式 如果看到这个还有一丢丢的印象,说明大家的基础都还不错.那么问题来了,大家都 ...
- 程序员必备十大排序算法
程序员必备十大排序算法 常见排序算法 基本概念 插入排序 直接插入排序 排序思路 排序过程 代码实现 算法分析 折半插入排序 排序思路 排序过程 代码实现 算法分析 希尔排序 排序思路 排序过程 代码 ...
- 视频教程-程序员必备算法课!(揭秘淘宝购物车算法)-机器学习
程序员必备算法课!(揭秘淘宝购物车算法) CSDN讲师名下集合了诸多业界知名讲师的公开课内容,内容涵盖人工智能.大数据.区块链等诸多热门技术领域的最佳技术实践,聚合美团.滴滴.AWS.科大讯飞等知名企 ...
- 蜡炬教育推荐:程序员必备的5本算法书籍
原标题:蜡炬教育推荐:程序员必备的5本算法书籍 由于近几年大数据.机器学习.人工智能方向的持续火爆,算法越来越被程序员重视,实际上算法比编程语言本身更加重要. 今天,蜡炬教育老师就为大家推荐几本经典的 ...
最新文章
- /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.15' not found的解决办法
- Linux的java服务配置步骤
- 牛客 - 「土」巨石滚滚(贪心)
- 解决 WPF 绑定集合后数据变动界面却不更新的问题
- Numpy数组的广播机制
- 【计算机网络复习 数据链路层】3.6.1 局域网
- 【计算机就业-算法工程师】校招想去互联网公司担任算法工程师该怎么准备
- HDU 1114 Piggy-Bank 简单DP
- wall 广播发送信息给所有user
- vivado综合阶段部分IP报错--需要安装y2k22补丁包
- 复盘:C语言中int a[][3]={1,2,3,4,5,6,7,8}什么意思,int a[3][]又是什么意思,结果为10的是
- Apache doris 使用过程中常见问题汇总
- 零信任解决方案在某医院落地实例学习记录
- 老程序员吐槽,今天面试了一个被培训班坑了的学生
- SpringBoot网页预览或下载pdf、图片
- Android自定义系列——13.Matrix Camera
- 一文读懂【数据埋点】
- UIQ全方位实现与ActiveSync进行数据交换(转)
- ORA-04098: trigger ‘xxx.xxx‘ is invalid and failed re-validation
- python自然语言处理-学习笔记(一)之nltk入门
热门文章
- c语言打开文件出现分段故障,C文件I / O中的分段故障11(Segmentation Fault 11 in C File I/O)...
- 高性能服务器io函数,操作系统中的I/O,及高性能IO模型
- Spring-tx-TransactionInterceptor类
- Java-获取本地都有哪些字体
- JavaSE12:集合简单总结
- starccm中文用户指南_【干货】Salesforce系统管理员认证考试指南
- 图片转可编辑ppt_电脑如何简单快速将图片转为文字,不用下载任何软件,免费使用。...
- java集合讲解_Java集合详解
- Linux中usb设置burst,Re: 关于IMX6UL第二个USB接口在linux驱动的问题
- 10本最值得推荐的区块链书