------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------
一、递归思想
递归是程序设计中的常用思想,其特点是在一个单独的函数中,会出现自身调用自身的现象。为什么会出现这样的现象呢?其实这也是来源于需求,我们在编写某些功能代码时,发现在代码编写过程在又有同样的需求出现,这时就出现了自身调用自身的现象,也说是说,功能上的重复产生了递归的应用。这是一种很自然的思维方法,类似于数学中数列的递推公式,就是数列的前一项通过某种数学运算,得出后一项,由前一项得后一项的这种运算,可以作用于数列后面的任一项的获取。这就是递归。
递归是相对于非递归而言的,也拿数列来说明。数列中求第n项,除了用从第一项,通过递推公式以外,还有一个求任一项的通项公式,自变量是项数,因变量是第n项。这就类似于递归算法与非递归算法的区别,通过下面的小代码,更能说明它们之间的区别:
这个小程序是实现十进制转二进制的功能,分别用到了非递归与递归算法,本程序只用来说明问题,故不考虑负数、0等其他情况。
public class BinaryTrans {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(toBin(60));
System.out.println(transBin(60, new StringBuilder()));
}
<span style="white-space:pre"> </span>//非递归实现方式
public static String toBin(int num) {
StringBuilder sb = new StringBuilder();//存储各二进制位的一个容器
while(num>0){
sb.append(num % 2);
num = num >>> 1;
}
return sb.reverse().toString();//由于二进制各位的获取是从低位到高位的,故返回时需要进行反转
}
//递归实现方式
public static String transBin(int num, StringBuilder sb) {//这里必须传入一个外部容器对象
if (num == 0){
return sb.reverse().toString();
}
sb.append(num % 2);
return transBin(num / 2, sb);//这里就用到了自身调用自身的手法
}
}
从上面的例子可以看出,程序功能的实现,既可以用递归的方式,也可用非递归的方式,不必拘泥于某一种方式。
二、递归结束条件
用递归进行编程时,很重要的一点就是递归结束条件的确定,否则递归的动作将是无止尽的,只会不断往方法体中深入而没有返回操作,这将导致内存的溢出。其实递归中,虽然递归用到的功能函数是同一个,但函数的参数列表其实是不同的,它们各自在栈内存中有各自的引用