java 利用二叉树精讲递归
递归说来不陌生,我看过许多关于递归的描述,但是他们并不能很好的描述出递归的神韵。
比如:
递归是一种自己调用自己的方法。 (这TD谁不知道)
你可以理解用爬层的关系去理解递归
你有一栋楼,却不知道有多少层,于是你从第一层,爬上了顶楼,知道了总共有n层。
但是你下楼时,匆忙,你忘记下到第几楼了,于是乎你又从第一层至顶楼,每一层都做标记(这就是递) 你从顶楼下来,发现一层的楼层数是递减的(这是归)
最神奇的是顶楼(它是不返回的)
就像路的尽头,无路可走怎么返回
123456789…
…987654321
这只是最简单的递归
真正的递归 :递只是归的参数,归才是程序想要的结果
我在电影院看电影,但我不知到我现在座位是第几排,我问前面一位这是第几排?他也不知道,他去问前面一位…当问到第一排时说,我是第一排,后…每一排后又返回来,我是n排,我是n+1排,最终我知道了第几排,这就是递归。
还看过一些一些用二叉树 先序 中序 ,后序 用描述进行简要的描述
还有的使用斐波那契数列数列进行描述的, 不可否认其证明递归的可行的。
但相对于初学者,的确不怎么友好,使之学习成本过高,其中(二叉树遍历是描述二叉树数据结构的,在绝大部分情况下是使用递归进行遍历的(不为什么,就是写法简单))和(斐波那契数列数列是递归遍历优化典型案例,能让人更透彻的看递归,提供一种递归崭新的算法思路。)
以上两个一般初学者的确看不懂递归高级用法
就是这样简单的东西的时越复杂,就让人很晕,其实不是这样的,递归递归,先递后归。简单的来说可以分成三种情况,第一种是只递不归的情况,第二种是只归(就是没有用上递的作用),第三种(即递又归,就是利用上递的过程作为参数使之结合归的应用。)
从结构上看递归算法
public static void main(String[] args) {
int[] objs = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
System.out.println("只递:");
zhiDi(objs,0);
System.out.println();
System.out.println("只归:");
zhiGiu(objs,0);
System.out.println();
System.out.print("既递又归:");
System.out.println();
jiDiYouGiu(objs,0);
System.out.println();
System.out.print("又递又归:");
System.out.println();
youDiYouGiu(objs,0);
}
//只递
public static void zhiDi(int[] array, int index) {
if (index < array.length) {
System.out.print(array[index]+",");
zhiDi(array, index + 1);
}
}
//只归
public static void zhiGiu(int[] array, int index) {
if (index < array.length) {
zhiGiu(array, index + 1);
System.out.print(array[index]+",");
}
}
//既递又归
public static void jiDiYouGiu(int[] array, int index) {
if (index < array.length) {
int num=array[index];
//System.out.print(array[index]+",");
jiDiYouGiu(array, index + 1);
System.out.print(num+array[index]+",");
}
}
//有递又归
public static void youDiYouGiu(int[] array, int index) {
if (index < array.length) {
//int xx=array[index];
System.out.print(array[index]+",");
youDiYouGiu(array, index + 1);
System.out.print(array[index]+",");
}
}
这是三种递归,也可以说是一种递归,但因为归(递)的顺序不同导致了,不同的返回结果
有时候我们可以简单的理解:
在执行递归方法前是正常的返回值(和普通for循环的执行顺序是一样的。)
然而在递归方法后执行的是递归执行后的与执行后的反向结果
下方是又递又归的内存分析f(n)、f(n+1+1)、f(n+1+1+1)、f(n+4)、f(n+5)、f(n+6)、f(n+7)、f(n+8)、
这是递归执行后的内存分布图,递归嵌套层调用自己,因为不能立刻达到运行结果导致内存不被释放会一直嵌套下去,直至运行结束再由下而上进行返回,有时候利用上递的参数处理归,看着结果就让人很混乱。
当递归边界太大时是已经很不适合画内存分析,可以简要测试自己写的程序是否达至自己的预期。
在很多时候,大家都会说递归的运行效率很低,实际上也的确如此,就如上图表示,但又碍于不可替代性,还是很多人会用递归。