递归的理解与设计
递归算法:是一种直接或者间接地调用自身的算法。在计算机编写程序中,递归算法对解决一大类问题是十分有效的,它往往使算法的描述简洁而且易于理解。
1,参考于书籍中的讲解:
递归的原理,其实就是一个栈(stack), 比如求5的阶乘,要知道5的阶乘,就要知道4的阶乘,4又要是到3的,以此类推,所以递归式就先把5的阶乘表示入栈, 在把4的入栈,直到最后一个,之后呢在从1开始出栈, 看起来很麻烦,确实很麻烦,他的好处就是写起代码来,十分的快,而且代码简洁,其他就没什么好处了,运行效率出奇的慢.
例: 求n的阶乘
int fac(n){if(n == 0 ||n == 1){return 1;}else{return n*fac(n-1); //自己调用自己,求n-1的阶乘}}
2,个人的经验性总结
设计一个递归算法,我认为主要是把握好如下四个方面:
1.函数返回值如何构成原问题的解
其实最先应该明了自己要实现的功能,再来设计函数的意义,特别是这个函数的返回值,直接关系到函数是否存在正确结果,函数返回什么递归子程序调用就会返回什么,而递归子程序调用的返回值会影响到最终结果,因此必须关注函数的返回值,子程序返回的结果被调用者所使用(也可以不使用),调用者又会返回,也就是说函数返回值是一致性的。
关键问题是如何由递归子程序构成原问题的解呢?很重要的问题,但是这里不能一概而论,
比如我们需要的是遍历的这个过程而不是递归子函数的返回的解,那么我们就可以不接收返回值或者直接写成void函数,典型的就是二叉树的三大遍历方式。
我们的解也有可能是由子问题的解组合而成(添加各种运算),无论如何这里应该试着从子问题和原文题的关系入手。
2.递归的截止条件。
截止条件就是可以判断出结果的条件,是递归的出口啊,最好总是先设计递归出口。
3.总是重复的递归过程。
一般简单的递归可以显式的用一个数学公式表达出来,比如前面的求阶乘问题。但是很多问题都不是简单的数学公式问题,我们需要把原问题分解成各种子问题,而子问题使用的是同样的方法,获取的是同样的返回值。
4.控制递归逻辑。
有的时候为了能实现目的,我们需要控制边界啊什么的,下面有具体介绍。
二,LeeCode实战理解