一、定义
计算机科学中,递归是一种解决计算问题的方法,其中解决方案取决于同一类问题的更小子集。
比如单链表递归遍历的例子:
void f(Node node){
if(node==null){
return;
}
f(node.next);
}
说明:
1.自己调用自己,如果说每个函数对应着一种解决方案,自己调用自己意味着解决文案是一样的(有规律的)
2.每次调用,函数处理的数据会较上次缩减(子集),而且最后会缩减至无需继续递归
3.内层函数调用(子集处理)完成,外层函数才能算调用完成。
二、思路
1.确定能否使用递归求解
2.推导出递推关系,即父问题与子问题的关系,以及递归的结束条件
例如之前遍历链表的递推关系为
-
深入到最里层叫递
-
从最里层出来叫做归
-
在递的过程中,外层函数内的局部变量(以及方法参数)并未消失,归的时候还可以用到。
例1-阶乘
用递归方法求阶乘
阶乘的定义n=1x2x3.....(n-2).(n-1).n,其中n为自然数,当然0!=1;
实现代码:
public static int f(int n){
if(n==1){
return 1;
}
return n*f(n-1);
}
拆解伪码如下,假设n初始值为3
f(int n = 3){ //递
return 3*f(n = 2){ //递
return 2*f(n = 1){ //递
if(n==1){
return 1;
}
}
}
}
例2-反向打印字符串
用递归反向打印字符串,n为字符在整个字符串str中的索引位置
递:n从0开始,每次n+1,一直递到n=str.length()-1
归:从n==str.length()开始归,从归打印,自然是逆序的
递推关系:
伪代码分析:
输入字符串:abcde
索引:01234
f(n)打印索引n的字符
f(0) //a
f(1) //b
f(2) //c
f(3) //d
f(4) //e
f(0){
f(1){
f(2){
f(3){
f(n==4){
return;
}
}
}
}
}
代码实现:
public class Factorial {
public static void printChar(String str,int n) {
if(n == str.length()) {
return;
}
printChar(str,n+1);
System.out.println(str.charAt(n));
}
public static void printChar2(String str,int n) {
if(n <=-1) {
return;
}
System.out.println(str.charAt(n));
printChar2(str,n-1);
}
public static void main(String[] args) {
/*
printChar2("abcde",0);*/
printChar2("abcde",4);
}
}
例3-递归实现二分法查找
递归终结条件:当i>j时,即跳出来。
package com.tfq.arithmetic.recursion;
/**
* @author: fqtang
* @date: 2024/05/24/16:12
* @description: 递归二分查找
*/
public class E03BinarySearch {
public static int search(int[] a, int target) {
return f(a, target, 0, a.length-1);
}
public static int f(int[] a, int target, int i, int j) {
if(i > j) {
return -1;
}
int m = (i + j) >>> 1;
if(target < a[m]) {
return f(a, target, i, m - 1);
} else if(a[m] < target) {
return f(a, target, m + 1, j);
} else {
return m;
}
}
}