递归的概念
若一个算法直接地或间接地调用自己本身,则称这个算法是递归算法。
问题的定义是递归的
例如:阶乘函数的定义
1 当n=1时
n! =
n*(n-1)! 当n>1时递归算法的设计方法
适宜于用递归算法求解的问题的充分必要条件是: (1)问题具有某种可借用的类同自身的子问题描述的性质
(2)某一有限步的子问题(也称作本原问题)有直接的解存在。
当一个问题存在上述两个基本要素时,设计该问题的递归算法的方法是:
(1)把对原问题的求解表示成对子问题求解的形式。
(2)设计递归出口。
递归算法应用
实例1:求n!问题。
package com.fbm.sixteen;
import java.util.Scanner;
public class Factorial {
public static long factorial(int num) {
if (num == 1) {
return 1;
} else {
return num * factorial(num - 1);
}
}
public static void main(String[] args) {
int num;
Scanner sc=new Scanner(System.in);
System.out.println("请输入一个整数:");
num=sc.nextInt();
System.out.println(num+"的阶乘是:"+Factorial.factorial(num));
}
}
实例2:设计折半查找递归算法。
package com.fbm.sixteen;
public class BinarySearch {
public static boolean bSearch(int[] array,int des,int low,int high){
if(low>high){
return false;
}
int mid=(low+high)/2;
if(des==array[mid]){
return true;
}else if(des<array[mid]){
return bSearch( array,des,low,mid-1);
}else{
return bSearch( array,des,mid+1,high);
}
}
public static void main(String[] args) {
int array[]={1,3,5,7,9,11,13,15,17,19,21};
System.out.println(BinarySearch.bSearch(array, 15, 0, array.length-1));
}
}
实例3:求波列纳契数列前N项之和。
从第三项起,每项是前两项之和。
1、1、2、3、5、8、13.....
package com.fbm.sixteen;
public class FibonacciSequence {
public static int getFibonacci(int n) {
if (n == 1 || n == 2) {
return 1;
} else {
return getFibonacci(n - 1) + getFibonacci(n - 2);
}
}
public static void main(String[] args) {
int n=5;
int result=0;
for(int i=n;i>=1;i--){
result+=FibonacciSequence.getFibonacci(i);
}
System.out.println("波列那契数列的前"+n+"项之和是:"+result);
}
}
实例4:求两个正整数的最大公约数。
package com.fbm.sixteen;
public class GCD {
public static int getGCD(int bignum,int smallnum){
if(smallnum<0||bignum<0){
return -1;
}else if(smallnum==0){
return bignum;
}else if(smallnum>bignum){
return getGCD(smallnum,bignum);
}else{
return getGCD(smallnum,bignum%smallnum);
}
}
public static void main(String[] args) {
System.out.println(GCD.getGCD(40, 35));
}
}
递归过程和运行时栈
递归函数的执行过程具有三个特点:
(1)函数名相同;
(2)不断地自调用;
(3)最后被调用的函数要最先被返回。
系统用于保存递归函数调用信息的堆栈称作运行时栈。
每一层递归调用所需保存的信息构成运行时栈的一个工作记录
栈顶的工作记录保存的是当前调用函数的信息,所以栈顶的工作记录也称为活动记录。