什么是递归?
递归就是一种调用自身来解决问题的方法,通过递归,可以将复杂的问题分解为更小的子问题,从而简化问题的解决过程
比如:可以把递归想象成一个迷宫游戏,当我们遇到一个迷宫,我们首先找到迷宫的出口,并记住这个位置,这就是终止条件.如何我们考虑迷宫的每一个岔路口,将每一个岔路口都可以当做一个迷宫,并重复之前的步骤,继续探索新的迷宫,直到到达终止条件
递归的实现原理:
-
定义递归函数的基本情况(终止条件)
-
在递归函数中调用自身,并缩小问题的规模
-
通过递归调用来解决子问题
-
确保递归调用能最终达到的基本情况,避免陷入无限递归
以下是常见的递归题目:
-
阶乘计算
阶乘是指从 1 乘到某个正整数 n . 阶乘的递归实现如下:
function factorial(n) {
// 终止条件
if (n === 0) {
return 1;
}
// 递归调用,缩小问题规模
return n * factorial(n - 1);
}
console.log(factorial(5)); // 输出:120
在阶乘函数中,如果 n=0 ,则返回 1,作为递归的终止条件 . 否则,通过递归调用计算 n 的阶乘
-
斐波那契数列
斐波那契数列是指前两个数字是 0 和 1 , 后续的每个数字之和 . 斐波那契数列的递归实现如下:
function fibonacci(n) {
// 终止条件
if (n === 0) {
return 0;
}
if (n === 1) {
return 1;
}
// 递归调用,缩小问题规模
return fibonacci(n - 1) + fibonacci(n - 2);
}
console.log(fibonacci(6)); // 输出:8
在斐波那契数列函数中 , 当 n=0 或 n=1 时 ,返回对应的固定值 .否则通过递归调用计算第 n 个斐波那契数
-
数组求和
对于一个给定的数组,计算数组中所有元素的和 . 数组求和的递归实现如下:
function sumArray(arr) {
// 终止条件
if (arr.length === 0) {
return 0;
}
// 递归调用,缩小问题规模
return arr[0] + sumArray(arr.slice(1));
}
console.log(sumArray([1, 2, 3, 4, 5])); // 输出:15
在数组求和函数中,当数组为空时,返回 0,作为递归的终止条件。否则从数组中取出第一个元素,并通过递归调用计算剩余数组元素的和。
在解决实际问题时,需要注意递归的终止条件和问题规模的缩减,以避免无限递归。
-
二叉树遍历
对于一个二叉树结构,可以使用递归来进行先序、中序和后序遍历。
class TreeNode {
constructor(val) {
this.val = val;
this.left = null;
this.right = null;
}
}
function preorderTraversal(root) {
if (!root) {
return [];
}
return [root.val].concat(preorderTraversal(root.left), preorderTraversal(root.right));
}
function inorderTraversal(root) {
if (!root) {
return [];
}
return inorderTraversal(root.left).concat(root.val, inorderTraversal(root.right));
}
function postorderTraversal(root) {
if (!root) {
return [];
}
return postorderTraversal(root.left).concat(postorderTraversal(root.right), root.val);
}
// 创建一个二叉树
const root = new TreeNode(1);
root.left = new TreeNode(2);
root.right = new TreeNode(3);
root.left.left = new TreeNode(4);
root.left.right = new TreeNode(5);
console.log(preorderTraversal(root)); // 输出:[1, 2, 4, 5, 3]
console.log(inorderTraversal(root)); // 输出:[4, 2, 5, 1, 3]
console.log(postorderTraversal(root)); // 输出:[4, 5, 2, 3, 1]
在二叉树遍历函数中,先序遍历先访问根节点,然后递归遍历左子树和右子树。中序遍历先递归遍历左子树,然后访问根节点,最后递归遍历右子树。后序遍历先递归遍历左子树和右子树,最后访问根节点。