一、基本含义
1.1 递归含义
自己调用自己的方法。
1.2 与循环的关系
1、循环都可以改写成递归,递归未必能改写成循环,这是一个充分不必要的条件。
2、在某些情况下(费波纳切数列,汉诺塔),使用递归会比循环简单得很多。
1.3 使用递归必要条件
1、 递归出口(终止递归的条件)
2、 递归表达式(规律)
技巧:在递归中常常是将问题切割成两个部分(1和整体的思想),这能够让我们快速找到递归表达式(规律)
二、示例
2.1 求和
X = 1+2+3+4+…+ n求和。
分析:
1、分成两部分,1和整体。
——整体(递归规律):sum(n) = sum(n-1) + n;
——1(递归出口):if(n == 1){ return 1}else{…}
2、书写代码。
public static int sum(int n){
int sum = 0;
if(n == 1){
sum = 1;
}else{
sum = sum(n-1) + n;
}
return sum;
}
2.2 数组最大值
给出一个数组,求该数组内部的最大值。
分析:
1、分成两部分,1和整体。
——整体(递归规律):把数组的[1,arr.length-1]个元素看成一个整体;
——1(递归出口):数组长度为1时,即为最大值。
2、书写代码。
// 普通法
public static int getMax(int[] arr){
int max = arr[0];
if(arr.length > 1){
int[] arr2 = new int[arr.length-1];
System.arraycopy(arr,1,arr2,0,arr2.length);
// arr2 = Arrays.copyOfRange(arr, 1, arr.length);
max = max > getMax(arr2) ? max : getMax(arr2);
}
return max;
}
// 边界法。R右边界索引,L左边界索引。
public static int getMax(int[] arr, int L, int R){
int max = arr[L];
if(L < R){
max = max > getMax(arr,L+1,R) ? max : getMax(arr,L+1,R);
}
return max;
}
2.3 冒泡排序递归写法
分析:
1、分成两部分,1和整体。
——整体(递归规律):把数组的[1,arr.length-1]个元素看成一个整体;
——1(递归出口):数组长度为1时,不需要排序。
2、书写代码。
public static void bubbleSort(int[] arr, int L, int R){
if(L < R){
int temp;
for(int i = L; i < R; i++){
if(arr[i] > arr[i+1]){
temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
}
}
bubbleSort(arr,L,R - 1 );
}
}
2.4 费波纳切数列
菲波那切数列:{1 1 2 3 5 8 13 21 34 55… n }
求出第n项是多少?
分析:
1、分成两部分,1和整体。
——整体(递归规律):前两项之和等于第三项;
——1(递归出口):数组长度为1时,出来了。
2、书写代码。
public static int fibonacci(int n){
if(n == 1 || n == 2){
return 1;
}else{
return (fibonacci(n - 2) + fibonacci(n - 1));
}
}