一、简介
递归(Recursion):指的是一种通过重复将原问题分解为同类的子问题而解决的方法。在绝大数编程语言中,可以通过在函数中再次调用函数自身的方式来实现递归。重点关注四个要素:输入参数,返回值,终止条件,递归拆解(如何递归下一层)
注意:递归是利用堆栈来实现的。每一次递推都需要一个栈空间来保存调用记录,每当进入一次函数调用,栈空间就会加一层栈帧。每一次回归,栈空间就会减一层栈帧。由于系统中的栈空间大小不是无限的,所以,如果递归调用的次数过多,会导致栈空间溢出。考虑栈溢出问题,可采用迭代等方法替代递归。
二、解题思路
确定终止条件、递推过程、回归过程
递推过程:指的是将原问题一层一层地分解为与原问题形式相同、规模更小的子问题,直到达到结束条件时停止,此时返回最底层子问题的解。
回归过程:指的是从最底层子问题的解开始,逆向逐一回归,最终达到递推开始时的原问题,返回原问题的解。
递归的数学模型是数学归纳法,具体步骤为
- 写出递推公式:
找到将原问题分解为子问题的规律,并且根据规律写出递推公式。 - 明确终止条件:
推敲出递归的终止条件,以及递归终止时的处理方法。 - 将递推公式和终止条件翻译成代码:
定义递归函数(明确函数意义、传入参数、返回结果等)。
书写递归主体(提取重复的逻辑,缩小问题规模)。
明确递归终止条件(给出递归终止条件,以及递归终止时的处理方法)
三、应用场景
- 树和图的遍历:
二叉树的前序、中序和后序遍历。
通用树的深度优先搜索(DFS)和广度优先搜索(BFS)。
图的遍历,如拓扑排序。 - 分治算法
快速排序、归并排序等排序算法。
汉诺塔问题。
最大子数组和问题。 - 动态规划:
斐波那契数列。
最长公共子序列(LCS)。
背包问题。 - 回溯算法:
解决N皇后问题。
旅行商问题(TSP)。
八皇后问题。 - 文件系统操作:
遍历文件目录结构。
计算目录大小或文件数量。 - 字符串处理:
字符串的模式匹配,如KMP算法。
正则表达式匹配。 - 数学计算:
阶乘、幂运算等。
计算组合数、排列数。 - 递归数据结构:
链表、树、图等数据结构的操作,如插入、删除、查找。
四、模板函数
// 递归函数模板
template <typename T>
T recursiveFunction(T n, T baseCase, T identity, std::function<T(T, T)> operation) {
// 基本情况
if (n == baseCase) {
return identity;
}
// 递归步骤
T result = operation(n, recursiveFunction(n - 1, baseCase, identity, operation));
return result;
}
//