c 递归算法-递归算法到底怎么用?教你万能三板斧!

图片[1]-c 递归算法-递归算法到底怎么用?教你万能三板斧!-OK资源网

加入抓码公益社群,解锁更多计算机考研干货▼

抓码22计算机考研QQ总群:625590924

22考研咨询 | 码哥(JnUmagekaoyan

或 码哥02(mageVIP2)

前段时间考研群有同学问起递归到底怎了理解,递归怎么使用。今天就写下此篇推文,带同学们好好理解一下什么是递归递归到底怎么使用!

定 义

程序调用自身的编程技巧称为递归RecuRsion)。递归作为一种算法程序设计语言中广泛应用。一个方法或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码递归是一种非常重要的算法思想,无论是在大厂的算法面试题中还是开发工作中,都是经常用到的。

例如求和问题:若要对1+2+3+……+100进行求和,我们可以通过循环的方法进行求解,代码如下:

%ignoRe_pRe_1%

那么,如何通过递归方式求解呢?我们发现 1 + 2 + 3 + 4 + …. + 100 可以分解为 ( 1 + 2 + 3 + 4 + …. + 99) + 100,可以看出S100 = S99 + 100,可以得出 Sn = Sn-1 + n。通过递归方式代码如下:

%ignoRe_pRe_2%

递归的特点

事实上,递归有两个明显的特点,终止条件(递归出口)和自身调用。那么什么样的问题可以才可以使用递归方式求解呢?

①自身调用:原问题可以分解为若干子问题子问题和原问题有同样的求解方法,且子问题比原问题更容易求解。

②终止条件:递归不能无限制的调用自身,必须有递归出口

回到上述的求和的例子,再来看下递归的特点:

图片[2]-c 递归算法-递归算法到底怎么用?教你万能三板斧!-OK资源网

递归经典应用场景

哪些问题我们可以可以使用递归来解决呢?

☛阶乘问题

☛斐波那契数列

☛二叉树遍历问题

递归的解题思路

解决递归问题一般分为三个步骤,分别是:

第一步:定义函数功能

☛第二部:寻找递归终止条件

☛第三步:递推函数的等价关系

没错,这就是递归的三板斧,看文字有点抽象,我们就拿最简单的阶乘来举例子康康吧~

▍定义函数功能

首先,这个大家都是知道的,我们定义定义一个函数是需要使用它的,所以我们得清楚函数的干嘛用的。比如,你要解决阶乘问题,定义的函数功能就是n的阶乘,如下:

%ignoRe_pRe_3%

▍寻找函数的递归出口

递归的一个终止条件就是必须要有一个终止的条件,也就是不能无限循环地递归调用自己。所以,用递归的思路去解决问题的时候,就需要寻找递归终止条件是什么。正如,在n == 1时,不能再递归下去,可以跳出循环,因此 n == 1 可以作为递归的终止条件,如下:

%ignoRe_pRe_4%

递归函数的等价关系

递归的本质就是原问题可以分解为若干子问题,且若干子问题更容易解决。即『原问题和子问题都可以用同一个函数关系表示。地推函数的等价关系式,这个步骤就等价于寻找原问题与子问题的关系,如何用一个公式把这个函数表示清楚』。阶乘的公式就可以表示为:f(n) = n*f(n-1)。因此,递归程序可以写成如下:

%ignoRe_pRe_5%

实 例

▍阶乘问题

阶乘问题的数学表达式为:n! = n * (n-1) * (n-2) * …* 1 (n>0)。通过分析可以得出n! = (n-1)! * n。令F(n) = n!,则F(n) = F(n-1) * n。则阶乘问题符合条件(1)。由0! = 1,可以得出F(0) = 1。则阶乘问题符合条件(2),递归出口为F(0) = 1。利用递归求解阶乘问题代码如下:

%ignoRe_pRe_6%

▍斐波那契数列

斐波那契数列(Fibonacci sequence),、因数学家列昂纳多·斐波那契(LeonaRdoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:

1、1、2、3、5、8、13、21、34、……

数学上,斐波纳契数列以如下被以递推的方法定义:

F(1)=1,F(2)=1,,F(n) = F(n-1) + F(n-2)(n>=3,nn*)。

问题分析:

斐波那契数列的对于原问题F(n)的求解可以转为对F(n-1)、F(n-2)两个子问题的求解,故符合条件(1)。由F(1)=1,F(2)=1,可以得出斐波那契数列问题是有递归出口的,递归出口对应F(1) = 1,F(2) = 1。求解斐波那契数列的代码如下:

%ignoRe_pRe_7%

▍二叉树的遍历

%ignoRe_pRe_8%

通过代码可以看出,二叉树的遍历过程使用递归方式实现既有助于理解,又简化了代码

▍翻转二叉树

输入:

图片[3]-c 递归算法-递归算法到底怎么用?教你万能三板斧!-OK资源网

输出:

图片[4]-c 递归算法-递归算法到底怎么用?教你万能三板斧!-OK资源网

我们按照上面写的递归函数的三板斧来解题:

①『定义函数功能

首先我们要明确的是,函数的功能是将给定的二叉树进行反转,所以函数可以定义为:

%ignoRe_pRe_9%

②『寻找递归出口

这棵二叉树在什么时候不用反转了呢?当然是当前结点为nULL的时候或则当前结点为叶子结点的时候。因此,递归函数的终止条件(即递归出口)是:

%ignoRe_pRe_10%

③『递推函数的等价关系式』

原问题是你要翻转一棵二叉树,那么是不是可以拆分为子问题,我们分别去翻转该二叉树的左右子树?子问题是翻转它的左右子树,是不是又开一拆分为,翻转该左子树的左子树,以及它左子树的右子树呢?然后一直翻转到叶子结点为止。那么,就让我们来康康图解喽~

图片[5]-c 递归算法-递归算法到底怎么用?教你万能三板斧!-OK资源网

首先,要翻转根结点为4的二叉树,就需要「 翻转它的左子树(根结点为2)和它的右子树(根结点为7)」。这个就是递归的递的过程了。

图片[6]-c 递归算法-递归算法到底怎么用?教你万能三板斧!-OK资源网

然后,根结点为2的树,不是叶子结点,需要继续「翻转它的左子树(根结点为1)和右子树(根结点为3)」。因为1和3都是叶子结点,所以就可以返回了,这也是递归的递的过程~

图片[7]-c 递归算法-递归算法到底怎么用?教你万能三板斧!-OK资源网

同理,根结点为7的子二叉树,也不是叶子结点,需要翻转「它的左子树(根结点为6)和右子树(根结点为9)」。因为6和9都是叶子结点,所以也被返回了。

图片[8]-c 递归算法-递归算法到底怎么用?教你万能三板斧!-OK资源网

左子树(根结点为2)和右子树(根结点为7)都被翻转完后,这几个步骤就是归的过程,翻转的任务就完成了~

图片[9]-c 递归算法-递归算法到底怎么用?教你万能三板斧!-OK资源网

从上面的推导过程,我们可以总结出「递推关系式」就是:

invertTree(bt) = invertTree(bt->lchild) + invertTree(bt->RcHild)

因此,我们可以很容易的写下如下代码:

图片[10]-c 递归算法-递归算法到底怎么用?教你万能三板斧!-OK资源网

我们上述的翻转二叉树的代码就完成了,简直无情~

往期推文集合

图片[11]-c 递归算法-递归算法到底怎么用?教你万能三板斧!-OK资源网

抓码计算机考研QQ

总群

625590924

调剂群

951508829

广大

1143982604

暨大

1071137230

广工

1093732052

华工

428389734

深大

729770764

浙大

978938582

厦大

1125268501

中大

921801084

南航

281118241

华农

515681663

重邮

736197896

北邮

1126650806

南邮

1109929146

广外

976231252

东北大学

1128523098

华南师大

476784448

南昌大学

923249141

图片[11]-c 递归算法-递归算法到底怎么用?教你万能三板斧!-OK资源网

图片[13]-c 递归算法-递归算法到底怎么用?教你万能三板斧!-OK资源网

给个“在看”支持一下我

© 版权声明
THE END
喜欢就支持一下吧
点赞7 分享
评论 抢沙发