什么是递归深度

  递归深度就是递归函数在内存中,同时存在的最大次数。

  例如下面这段求阶乘的代码:

  int factorial(int n) { if (n == 1) { return 1; } return factorial(n - 1) * n;}

  当n=100时,递归深度就是100。一般来说,我们更关心递归深度的数量级,在该阶乘函数中递归深度是O(n)O(n),而在二分查找中,递归深度是O(log(n))O(log(n))。在后面的教程中,我们还会学到基于递归的快速排序、归并排序、以及平衡二叉树的遍历,这些的递归深度都是(O(log(n))(O(log(n))。注意,此处说的是递归深度,而并非时间复杂度。

  太深的递归会内存溢出

  首先,函数本身也是在内存中占空间的,主要用于存储传递的参数,以及调用代码的返回地址。

  函数的调用,会在内存的栈空间中开辟新空间,来存放子函数。递归函数更是会不断占用栈空间,例如该阶乘函数,展开到最后n=1时,内存中会存在factorial(100), factorial(99), factorial(98) ... factorial(1)这些函数,它们从栈底向栈顶方向不断扩展。

  当递归过深时,栈空间会被耗尽,这时就无法开辟新的函数,会报出stack overflow这样的错误。

  所以,在考虑空间复杂度时,递归函数的深度也是要考虑进去的。

  大连包皮手术哪家医院好 http://www.xasgnk.cn

  大连性病医院 http://nk.84211111.com

  大连人流医院 http://www.fkyy120.net

  大连治疗早泄医院 http://www.84211111.net

  大连男科医院哪个好 http://hnyy.01ny.cn

  大连人流手术费用 http://www.120dlbh.com

  Follow up:

  尾递归:若递归函数中,递归调用是整个函数体中最后的语句,且它的返回值不属于表达式的一部分时,这个递归调用就是尾递归。(上例factorial函数满足前者,但不满足后者,故不是尾递归函数)

  尾递归函数的特点是:在递归展开后该函数不再做任何操作,这意味着该函数可以不等子函数执行完,自己直接销毁,这样就不再占用内存。一个递归深度O(n)O(n)的尾递归函数,可以做到只占用O(1)O(1)空间。这极大的优化了栈空间的利用。

  但要注意,这种内存优化是由编译器决定是否要采取的,不过大多数现代的编译器会利用这种特点自动生成优化的代码。在实际工作当中,尽量写尾递归函数,是很好的习惯。

  而在算法题当中,计算空间复杂度时,建议还是老老实实地算空间复杂度了,尾递归这种优化提一下也是可以,但别太在意。

  --------------------- 本文来自 湾区Python 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/BTUJACK/article/details/82958574?utm_source=copy

10-07 16:38