一、什么是递归
1、递归的定义
2、递归的思想
3、递归的三要素
二、递归的经典例题
1、阶乘
2、斐波那契数列
3、回文串
4、杨辉三角
5、汉诺塔
6、二分查找
三、递归的些许限制
四、递归经典例题的循环求解
一、递归
1、递归的定义
简单来说,递归,就是自己实现了一个函数,通过这个函数自己使用或调用自己去完成问题的求解。
只是实现一个函数有点笼统,但先这样理解。
2、递归的思想:将大规模的问题变成小规模的问题,问题不变,规模变小
那么,咋就可以搞这样一个函数呢?
求解一个问题的时候,发现这个问题可以由许许多多的小问题求解,而且这些问题的关系是:我们求解问题1时,只需要知道问题2的答案便可得到问题1的解,知道了问题3的解也就知道了问题2的答案…依次推啊推,直到我们搞到这种问题结构的最后一个问题x,发现,A~,它的解是生来就有的(没有它就蒙了,我搞谁的答案呢?),这也是问题或递归的终止条件。
3、递归的三要素
1)处理方法:解决大一点规模的问题时,提取重复逻辑,缩小问题规模
2)明确递归的终止条件
3)给出在终止条件下的解决办法
二、递归的典型例题
1、阶乘
public static int factorial(int n) {
//递归终止条件
if(n == 1){
//解决办法
return 1;
}
if(n > 1){
//重复逻辑
return n * factorial(n - 1);
}
return -1;
}
2、斐波那契数列
public static int fibonacci(int n) {
//递归终止条件
if (n == 1 || n == 2) {
//如何解决
return 1;
}
if(n > 2) {
//缩小问题规模,提取重复逻辑
return fibonacci(n - 1) + fibonacci(n - 2);
}
return -1;
}
3、回文串
public static boolean isPlalindromeString(String s, int start, int end){
if(s == null || s.length() == 0 || start > end) return false;
if(start < end){
//递归的终止条件
if(s.charAt(start) != s.charAt(end)){
//解决办法
return false;
}else {
//缩小问题规模,提取重复逻辑
return isPlalindromeString(s, start+1, end-1);
}
}
return true;
}
4、杨辉三角
private static int description(int i, int j) {
//递归终止条件
if (j == 0 || i == j) {
//解决办法
return 1;
} else {
//重复逻辑
return description(i - 1, j) + description(i - 1, j - 1);
}
}
5、汉诺塔
public static void hanoi(int n, char one, char two, char three) {
//将n个盘从one座借助two座移到three座
//终止条件
if (1 == n) {
//然后呢
System.out.println(one + " -->" + three);
} else {
//重复逻辑
hanoi(n - 1, one, three, two);
System.out.println(one + " -->" + three);
hanoi(n - 1, two, one, three);
}
}
6、二分搜索
public static int binarySearchRecur(int[] list, int key, int low, int high) {
if (low <= high) {
int middle = (low + high) >> 1;
//终止条件
if (list[middle] == key) {
//解决办法
return middle;
//重复逻辑
} else if(list[middle] > key){
return binarySearchRecur(list, key, low, --middle);
} else {
return binarySearchRecur(list, key, ++middle, high);
}
}
return -1;
}
三、递归的小瑕疵
递归算法的运行效率比较低,无论是耗费的计算时间还是占用的存储空间都比非递归算法要多。
而且如果递归函数调用的层次很深,有可能导致函数调用栈溢出。
四、循环实现
1、阶乘
public static long factorialByCircu(int n){
if( n < 0){
return 0;
}
long result = n;
while(n > 1){
n--;
result *= n;
}
return result;
}
2、斐波那契数列
public static long fibonacciByCicur(int n){
if(n == 1 || n == 2){
return 1;
}
int first = 1;
int second = 1;
int result = 0;
for(int i=3; i<=n; i++){
result = first + second;
first = second;
second = result;
}
return result;
}
3、回文串
public static boolean isPlalindromeStringByCircu(String s){
if(s == null || s.length() == 0) return false;
int start = 0;
int end = s.length()-1;
while(start < end){
if(s.charAt(start) != s.charAt(end)){
return false;
}else{
start ++;
end --;
}
}
return true;
}
4、杨辉三角
public static void yongTriangle(int n) {
int[][] arr = new int[n][n];
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
if (j == 0 || i == j) {
arr[i][j] = 1;
} else if (i - 1 >= 0) {
arr[i][j] = arr[i - 1][j] + arr[i - 1][j - 1];
}
}
}
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j <= i; j++) {
System.out.print(arr[i][j] + " ");
}
System.out.println();
}
5、汉诺塔
略略略 -.-
6、二分搜索
public static int binarySearch(int[] list, int value){
int left = 0;
int right = list.length;
while (left <= right) {
int middle = (left + right) / 2;
if (value == list[middle]) {
return middle;
}
if (value < list[middle]) {
right = --middle;
}
if (value > list[middle]) {
left = ++middle;
}
}
return -1;
}