预备知识:
1、递归函数是直接调用自己或通过一系列的调用语句间接地调用自己的函数。递归函数必须至少有一个退出条件,即不再继续调用自己而是返回值退出。
2、栈,栈既是一种先进后出的数据结构,也可以指具有以上属性的动态内存区域。
3、递归函数和栈的关系:递归函数的运行其实就是前行和退回。递归过程退回的顺序是前行顺序的逆序。在退回过程中,可能要执行某些动作,包括恢复在前行过程中存储起来的某些顺序。这种退回返回顺序很符合栈数据结构特征,所以编译器就是用栈实现递归,也就是说,对于每一层递归,函数的局部变量、参数值以及返回地址 都被压人栈中。在退回的阶段,位于栈顶的局部变量、参数值和返回地址都被弹出,用于返回调用层次中执行代码的其他部分。
package cn.edu.zju; public class Digui { public static void main(String[] args) { Digui.sysOut1(4); /* 对于递归,先正向到达深度的最深4-3-2-1,然后按照深入的逆序1-2-3-4回头执行正向深入时尚未执行的部分.正着走一遍,必须反着走一遍,无论正着的一遍是怎样结束的. * 4 3 2 1【正向深入到最深处的位置】 0 最后一句 -99【这里开始逆向回头N=1。逆序回头到N为1时未执行完的部分为第2句和第3句,执行第2句时,先执行4《结果就是上面的-99》,再执行3《结果就是这里的“最后一句”》,这里是第2句执行的编号为4 的结果】 最后一句【这里是第2句执行的编号为3的结果】 最后一句【这里是第3句的结果,是逆序回头到N为1时执行完第2句之后再执行的这个第3句,,这样就解释了为什么连续两次递归最后一句要执行两次】 -98【逆序回头到N为2时未执行完的部分sysOut1(N-100);】 最后一句【逆序回头到N为2时未执行的打印System.out.println("最后一句");】 最后一句【逆序回头到N为2时未执行的打印System.out.println("最后一句");】 -97 最后一句 最后一句 -96 最后一句 最后一句 */ } public static void sysOut1(int N){ System.out.println(N);//4 if(N>0){ sysOut1(N-1);//1 sysOut1(N-100);//2 } System.out.println("最后一句");//3 } } |
注意:使用递归的归并排序(橙皮书P170)以及使用递归的快速排序(橙皮书P182)使用的都是这种连续的两次递归。