什么是递归呢?
递归(英语:Recursion),又译为递回,在数学与计算机科学中,是指在函数的定义中使用函数自身的方法。递归一词还较常用于描述以自相似方法重复事物的过程。例如,当两面镜子相互之间近似平行时,镜中嵌套的图像是以无限递归的形式出现的。也可以理解为自我复制的过程。
递归就是自身调用自身!
下面我会以一个简单的例子来切入 较为详细的解释下递归的过程
求一个数组中的最大值
当然最简单的思路 我们遍历一遍整个数组
找出它的最大值 这样子当然可以
但是为了让大家更好的理解递归 我们这里使用递归调用的方法来做一下
这里代码表示如下
我们来一行行的解读
int Get_Max(int *arr , int left , int right) { // 首先是极限值 if (left>=right) { return arr[left]; } // 如果没到极限值 那么找左右两边的最大值 比较一下返回大的就好 int mid = left + (right - left) / 2; int leftmax = Get_Max(arr, left, mid); int rightmax = Get_Max(arr, mid + 1, right); if (leftmax>rightmax) { return leftmax; } else { return rightmax; } }
首先递归我们第一个考虑的肯定是极限值对吧
假如我们到了极限了 数组的左右相等找最大值 那么我们肯定返回随便哪个都可以啊
if (left>=right) { return arr[left]; }
假如我们没有到极限值
那么我们就开始找它的左半边的最大值和右半边的最大值
代码表示如下
// 如果没到极限值 那么找左右两边的最大值 比较一下返回大的就好 int mid = left + (right - left) / 2; int leftmax = Get_Max(arr, left, mid); int rightmax = Get_Max(arr, mid + 1, right);
那么最后我们要求的是最大值是吧
这个时候只需要返回左边和右边当中的最大值 是不是就可以了啊
代码表示如下
if (leftmax>rightmax) { return leftmax; } else { return rightmax; }
这之后就能得到我们的最大值啦
来看看结果符合不符合预期
再之后我们改变下最大值试试看
这里还是可以找到最大值的
递归的底层原理
很多人认为递归很神奇是吧 像魔法一样 明明我们没有写中间的函数过程 它却把最后的过程给我们算出
来了
其实递归并不是魔法
而是运用了一个叫做系统栈的东西
我们再上篇博客中已经学习栈这个数据结构
系统栈跟我们的栈结构类似
还是以我们上面那个函数为例
在栈上的调用过程如下图
大概结构就是这样子的
那么 我们这里给出一个判断题
所有的递归函数都能写成非递归形式
这句话对吗?
显然是正确的
因为我们学了栈这个数据结构 没有系统栈大不了我们来手动压栈
Master公式
那么 这里的a b c分别是什么意思呢?
a
a就是在这个递归函数从上到下走一遍(不进入函数内部) 主函数被调用多少次
比如说这里面
实际上一躺下来就调用了两次主函数
所以说这里的a = 2
b
那么b又是什么意思呢?
我们这里可以简单理解为
函数内部的主函数调用将函数分成了几部分?
如果说分成了两部分 这个b就是2
如果说分成了三部分 这个b就是3
d
d就很简单了
我们将所有的函数都注释掉 像这样子
然后再看看里面的时间复杂度是多少
很显然 是常数次 所以是O(1)
那么这个时候我们的d就是0
Master公式记忆方法
首先我们要记住要比较的两个数
Log aB 以及 d
如果d大 那么d就是N的指数
如果前面大 那么前面一项就是N的指数
如果相等 那么N的指数还是d 不过后面还要乘一个LogN
(最后这个比较特殊 要花一点时间记一下)
总结
本篇博客较为简单的介绍了递归的底层原理和Master公式
由于博主的水平有限所以难免博客中会出现纰漏 希望大佬们看到之后可以即使指正
最后如果这篇博客帮助到了你 别忘了一键三连啊
阿尼亚 哇酷哇酷!