递归


递归是一种常见的解决问题的方法,即把问题逐渐简单化。递归的基本思想就是“自己调用自己”,一个使用递归技术的方法将会直接或者间接的调用自己。利用递归可以用简单的程序来解决一些复杂的问题。比如:斐波那契数列的计算、汉诺塔、快速排序等问题。


Java 递归和折半查找_java

❤️ 使用递归实现 n!

public class TestRecursion1 {
public static void main(String[] args) {
//使用循环求n!
int n = 6;
int fac = 1;
for(int i=1;i<=n;i++){
fac = fac * i;
}
System.out.println(fac);
//使用递归求n!
int result = fac(n);
System.out.println(result);
}
public static int fac(int n){
int result;
if(n==1){
result = 1;
}else{
result = n * fac(n-1);
}
return result;
}
}

递归的调用过程。

Java 递归和折半查找_数据结构_02

❤️ 使用递归实现斐波那契数列

斐波那契数列(Fibonacci sequence),又称黄金分割数列、因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:1、1、2、3、5、8、13、21、34、……在数学上,斐波那契数列以如下被以递推的方法定义:F(1)=1,F(2)=1, F(n)=F(n-1)+F(n-2)(n>=3,n∈N*)。

public class TestRecursion2 {
public static void main(String[] args) {
//使用循环实现
int numn_2 = 1;
int numn_1 = 1;
int numn=0 ;
int n= 40;
long startTime = System.currentTimeMillis();
for(int i=3;i<= n;i++ ){
//得到i项的值
numn = numn_1+ numn_2;
//改变numn_2和numn_1的值
numn_2 = numn_1;
numn_1 = numn;
}
System.out.println(n+" "+numn);
long endTime = System.currentTimeMillis();
System.out.println("循环花费的时间:"+(endTime - startTime));
//使用递归实现
startTime = System.currentTimeMillis();
System.out.println(n+" "+fibo(n));
endTime = System.currentTimeMillis();
System.out.println("递归 花费的时间:"+(endTime - startTime));
}
public static int fibo(int n){//1,2,3.....n
//给结果指定初始值
int result = 0;
//使用递归求结果
if(n==1 || n==2){
result = 1;
}else{
result = fibo(n-2) + fibo(n-1);
}
//返回结果
return result;
}
}

递归问题的特点


一个问题可被分解为若干层简单的子问题 子问题和其上层问题的解决方案一致 外层问题的解决依赖于子问题的解决


递归结构包括两个部分:


递归结束条件:什么时候不调用自身方法。如果没有条件,将陷入死循环。 递归体。解答:什么时候需要调用自身方法。


递归的优点


自然的思路,简单的程序


递归的缺点


但是递归调用会占用大量的系统堆栈,内存耗用多, 在递归调用层次多时速度要比循环慢的多


注意事项


  • 任何能用递归解决的问题也能使用迭代解决。当递归方法可以更加自然地反映问题,并且易于理解和调试,并且不强调效率问题时,可以采用递归。
  • 在要求高性能的情况下尽量避免使用递归,递归调用既花时间又耗内存。

折半查找


折半查找又称为二分查找,这种查找方法需要待查的查找表满足两个条件:
首先,查找表必须使用顺序存储结构;
其次,查找表必须按关键字大小有序排列。


key=21的查找过程

Java 递归和折半查找_折半查找_03

key=85的查找过程

Java 递归和折半查找_折半查找_04

❤️ 非递归的折半查找

public class BinarySearch {
public static void main(String[] args) {
int[] array = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
System.out.println(searchLoop(array, 101));
}
public static int searchLoop(int[] array, int findValue) {
// 如果数组为空,直接返回-1,即查找失败
if (array == null) { return -1; }
// 起始位置
int start = 0;
// 结束位置
int end = array.length - 1;
while (start <= end) {
// 中间位置
int middle = (start + end) / 2;
// 中值
int middleValue = array[middle];
if (findValue == middleValue) {
// 等于中值直接返回
return middle;
} else if (findValue < middleValue) {
// 小于中值时在中值前面找
end = middle - 1;
} else {
// 大于中值在中值后面找
start = middle + 1;
}
}
// 返回-1,即查找失败
return -1;
}
}

❤️ 递归的折半查找

public class BinarySearch {
public static void main(String[] args) {
int[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
System.out.println(binSearch(array, 10));
}
public static int binSearch(int array[], int key) {
int start = 0;
int end = array.length - 1;
return binSearch(array, start, end, key);
}
public static int binSearch(int array[], int start, int end, int key) {
int mid = (end + start) / 2;
if (start > end) {
return -1;
}
if (array[mid] == key) {
return mid;
} else if (key > array[mid]) {
return binSearch(array, mid + 1, end, key);
} else {
return binSearch(array, start, mid - 1, key);
}
}
}

谢谢大佬~

Java 递归和折半查找_java_05


作者:香芋味的猫丶