递归函数:指调用自己的函数。
一.递归的特点
1.函数一般使用if-else或分支语句来实现。
2.存在一个或多个条件用来停止递归。
3.每次递归调用会使问题逼近终止条件或情况,直到转化为该条件或情况为止。
(递归递归先递后归,递:层层递进只到最终条件为止,归:带着得到的结果一层层返回到原问题。)
二.递归的分类
递归分为两种,直接递归和间接递归。
1.直接递归即函数直接自己调用自己。
代码示例:
#include <iostream>
using namespace std;
int fac(int);
int main()
{
cout << "输入一个数: ";
int n;
cin >> n;
cout << n << "的阶乘 为" << fac(n);
return 0;
}
int fac(int n)
{
if (n == 0)
return 1;
else
return n * fac(n - 1);
}
2.间接递归可以是A函数调用B函数时,B函数反过来调用A函数。也可以是A函数数调用B函数,B函数调用C函数,C函数调用A函数。
三.递归辅助函数(recursive helper function)
递归辅助函数是递归程序设计中常用的一种方法。
下面是运用递归来检查字符串是否是回文的函数代码
bool isPalindrome(const string& s)
{
if (s.size()<= 1)
return true;
else if (s[0] != s[s.size() - 1])
return false;
else
//节选字符串的一部分
return isPalindrome(s.substr(1, s.size() - 2));
}
可以看到每次调用递归的时候都要创建一个新的字符串,占用了大量资源,所以说这个函数的效率是不高的。
为了避免创建新的字符串,我们可以选择通过建立两个下标 low ,high 来指出子串的范围。
bool isPalindrome(const string& s, int low, int high)
{
if (high <= low)
return true;
else if (s[low] != s[high])
return false;
else
return isPalindrome(s, low + 1, high - 1);
}
bool isPalindrome(const string& s)
{
return isPalindrome(s, 0, s.size() - 1);
}
声明一个重载函数,来接受额外的参数这是递归程序设计中常用的方法,这个函数即上文中的isPalindrome(const string& s, int low, int high)就是我们所说的递归辅助函数。
(注:代码节选自introduction to programming with c++ 第三版)
四.尾递归
尾递归函数可以大大减少堆栈空间
定义: 一个递归函数返回递归调用之后没有要执行的操作,这种递归函数称之为为尾递归(tail recursive)。
如上文代码示例中的检查字符串是否是回文的递归函数即为尾递归函数, 而阶乘的递归函数则不是尾递归函数。
return n * fac(n - 1); //返回后有操作执行
return isPalindrome(s.substr(1, s.size() - 2));//无操作执行
非递归函数通常可以转换为一个尾递归函数。以阶乘函数为例,给它定义一个递归辅助函数int fat(int n,int r)。r 用来接收上次递归调用的结果。
注意事项:
每次程序调用递归函数是,系统要为所有的局部变量和参数分配内存空间,这可能耗费大量的内存所以递归一定要有终止条件,保证递归能够停止下来,否则会发生栈溢出。
来源:https://blog.csdn.net/weixin_42199022/article/details/99304964