开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第3天,点击查看活动详情
前言
递归是一种非常重要的算法思想,无论你是前端开发,还是后端开发,都需要掌握它。在日常工作中,统计文件夹大小,解析xml文件等等,都需要用到递归算法。它太基础太重要了,这也是为什么面试的时候,面试官经常让我们手写递归算法。本文呢,将跟大家一起学习递归算法~
什么是递归?
递归,在计算机科学中是指一种通过重复将问题分解为同类的子问题而解决问题的方法。简单来说,递归表现为函数调用函数本身(自己调用自己)。
递归:指在当前方法内调用自己的这种现象。
递归的分类:
递归分为两种,直接递归和间接递归。
直接递归称为方法自身调用自己。
间接递归可以A方法调用B方法,B方法调用C方法,C方法调用A方法。
注意事项:
递归一定要有条件限定,保证递归能够停止下来,否则会发生栈内存溢出。
在递归中虽然有限定条件,但是递归次数不能太多。否则也会发生栈内存溢出。
构造方法,禁止递归。
递归应用场景
- 阶乘问题
- 二叉树深度
- 汉诺塔问题
- 斐波那契数列
- 快速排序、归并排序(分治算法体现递归)
- 遍历文件,解析xml文件
简单递归的代码例子
public int sum(int n) {
if (n <= 1) {
return 1; //结束条件
}
return sum(n - 1) + n;
}
递归解题思路
第一步,定义函数功能
第二步,寻找递归终止条件
第二步,递推函数的等价关系式
累加递归
public class Demo {
public static void main(String[] args) {
//计算1~num的和,使用递归完成
int num = 5;
// 调用求和的方法
int sum = getSum(num);
// 输出结果
System.out.println(sum);
}
/*
通过递归算法实现.
参数列表:int
返回值类型: int
*/
public static int getSum(int num) {
/*
num为1时,方法返回1,
相当于是方法的出口,num总有是1的情况
*/
if(num == 1){
return 1;
}
/*
num不为1时,方法返回 num +(num-1)的累和
递归调用getSum方法
*/
return getSum(num-1)+n;
}
}
图解
阶乘同理可得
public class DiGuiDemo {
//计算n的阶乘,使用递归完成
public static void main(String[] args) {
int n = 3;
// 调用求阶乘的方法
int value = getValue(n);
// 输出结果
System.out.println("阶乘为:"+ value);
}
/*
通过递归算法实现.
参数列表:int
返回值类型: int
*/
public static int getValue(int n) {
// 1的阶乘为1
if (n == 1) {
return 1;
}
/*
n不为1时,方法返回 n! = n*(n-1)!
递归调用getValue方法
*/
return getValue(n - 1)*n;
}
}
斐波那契数列
斐波那契数列指的是这样一个数列:
0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946,17711
public class Fibonacci {
public static void main(String[] args) throws Exception {
int f = fun(30);
System.out.println(f);
}
/**
*递归算法(牢记) 能够提高效率
*Functions:斐波那契数列: 1 1 2 3 5.....返回斐波那契数列的第20项数值
*/
public static int fun(int a) throws Exception {
if(a==0){
throw new Exception("参数异常错误"); //自定义异常
}
if(a==1||a==2) {
return 1;
}else{
return fun(a-1)+fun(a-2);
}
}
}