Hello,屁民。今天总结递归算法,
递归是十分耳熟能详的一种算法类型,也是一种暴力(我猜的)算法。但是其解题的效率相对较低,占用空间资源较多。
参考:
https://blog.youkuaiyun.com/allenchenhh133/article/details/80291252
https://blog.youkuaiyun.com/qmdweb/article/details/80537602
https://blog.youkuaiyun.com/bobbypollo/article/details/79891556
概念
递归算法(英语:recursion algorithm)在计算机科学中是指一种通过重复将问题分解为同类的子问题而解决问题的方法。(百度百科)
直接或者间接调用自身的算法。将一个大的问题层层转换为与原问题相似的较小的问题,直到有解,然后将小问题的解一步步返回到原问题得到最终解。
最重要的一点就是,大的问题假设小问题已经解决!基于已经解决的小问题再进行处理当前问题。最小问题的解即为边界条件。通过已解决的小问题解大问题的过程就是递归方程。
在算法中使用递归,往往会使得算法看起来简洁,易于理解。
比喻如下
儿子:爸爸,为什么要吃蔬菜?
爸爸:吃蔬菜是为了补充维生素。
儿子:为什么要补充维生素?
爸爸:为了长高。
儿子:为什么要长高?
爸爸:这样你们班的娜娜就喜欢你了。
儿子:原来是这样,那再给我炒一盘好吗。
Fibonacci
最经典的递归无疑。
无穷数列 1,1,2,3,5,8,13,21,34,55,89,... ,称为Fibonacci数列。可以使用递归表示,
n = 0, n = 1 是边界条件,当 n >= 2 时是递归方程。二者构成递归算法的基本元素。
二叉树的先序遍历
与Fibonacci数列一样典型的递归问题。不同于普通的递归算法,二叉树先序遍历每层需要调用两次递归
递归与栈
递归就是出入栈。
由前面的讲解大概可以看出,求解过程就是先入后出,类似于栈处理过程。
我们知道函数调用是将函数放入函数栈中,当递归调用的层数过于深就会导致栈溢出而死机。所以,虽然递归调用看起来优雅,但是老司机看重的不是优雅,而是高效(风骚)。
既然递归调用有这样致命的缺点,我们就会想将递归函数非递归化,这个后面再聊。
递归复杂度判定定理(Master定理)
参考分治算法