前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >深入浅出的理解一下JAVA的递归思想

深入浅出的理解一下JAVA的递归思想

作者头像
何处锦绣不灰堆
发布2020-05-29 09:42:03
5980
发布2020-05-29 09:42:03
举报
文章被收录于专栏:农历七月廿一农历七月廿一

写在前面

我呢一直写的是js相关的文章,以至于很多人认为我是一个标准的前端工程师,这也不奇怪,后端的谁会瞎搞js呢?其实呢我是一个地地道道的写java的菜逼,嗯,菜逼,只是公司的要求被迫我写了js,可能是看我java太差了,或者是我长的比较适合写js等等吧,总之导致的结果是我写了很长一段时间的js,今天呢js写的也不少了,所以今天我想写一篇关于java的文章,看看我是不是还和以前一样的菜逼,其实写了那么久的js给我感觉是和java真的很多地方是一样的,两种语言虽然说是不同的,但是其实仔细的体会一下,也没什么特别不同的地方,这里说多说一点,很明显的一个区别可能就是java是强类型语言,js是弱类型语言,但是java是面向对象编程的, js其实也是的,所谓的强类型语言就是说呢他不同的变量必须使用不同的类型来声明,不能像js一样所有的都是var或者是let,当然还有很多大大小小的区别,这里我就不献丑了,毕竟看我的文章的可能还有java的大神,我就不班门弄斧了,今天要说的是java的递归的思想,为什么要说这个呢?其实很简单,就是觉得这个是java一个很有意思的地方,今天我们就看看有意思的在哪里!

首先我们要明白什么是递归思想:

我们都知道,java里面的每一个功能都会被封装成一个方法,第一是为了装逼,第二呢是为了更好的维护,方法的原则是每一个功能封装成一个方法,这也是java原子性的体现,那么到这里我们就会想啊,既然方法写出来了,那么一定是需要别的方法调用的是不是,不然单写一个没有被调用过得方法没有什么意义是不是,就好像你写一个带有参数的方法,形参写好了,但是没有人调用,也就是没有实参传进来,那么这个方法我们认为是没有意义的方法,所以写了方法就一定要被调用的才是有意义的,那么既然是被调用,就要思考一个问题,被谁调用?

这里我们写一个例子:

代码语言:javascript
复制
package com.gaojizu.studybymyself;
/**
 * 测试递归的思想
 *@author clearlove
 */

public class Test_Recursion {
	
	public static void test01() {
	    test02();
		System.out.println("test01");
		
	}
	public static void test02() {
		System.out.println("test02");
	}
	
	public static void main(String[] args) {
	    test01();
		
	}

}

ok这里我们可以看到我写了两个方法,test01和test02,那么这里我们会想这个很简单的啊,函数从mian进入,执行01

的时候将执行02的方法:

没有问题,那么我们难道不想一下为什么我们不可以01里面直接调用01呢?自己调用自己会有什么后果呢?

我们可以试一下:

代码语言:javascript
复制
package com.gaojizu.studybymyself;
/**
 * 测试递归的思想
 *@author clearlove
 */

public class Test_Recursion {
	
	public static void test01() {
	    test01();
		System.out.println("test01");
		
	}
	public static void test02() {
		System.out.println("test02");
	}
	
	public static void main(String[] args) {
	    test01();
		
	}

}

这个时候我们看一下:

ok这里会报错,什么意思呢?很简单内存溢出了,为什么呢?这里其实就是递归的一个简单的雏形思想,自己调用自己,为什么是雏形呢?因为出错了啊,不完美啊,为什么会出错呢?接着往下看,既然出错了我们就要先搞明白哪里出的问题,我们绘图模拟一下他的代码执行的过程:

没有画之前我们先debug一下,看看这个代码怎么执行的:

这里我们会发现一个问题,就是代码走到test01的时候啊不走了,为什么不走了呢?代码什么情况下会不走?第一代码执行结束,第二代码不知道怎么结束!这个显然就是不知道怎么结束了!

我们画一下:

这里就很有意思了,代码走到这里01的时候他发现下面要执行的是test01,也就是自己,所以就直接回到方法头部开始重新执行,第二次还是自己,所以就陷入一个无限循环中,这里可能你们一看就明白,但是很少有人去思考这里的问题,这个情况会导致在我们计算机中有限的内存出现无限的数据,所以导致了内存溢出!可能很多人就说了,这不是和C语言中的Goto方法差不多嘛!虽然java中的goto已经不让用了,但是思想其实是差不多的,虽然不让用了但是我们还是可以在java中找到他的影子的,例如下面的代码:

代码语言:javascript
复制
/*
 * 
 * author : clearlove
 * 测试一下c语言中的goto的思想用法
 * 写一个101到150之间的质数
 */
package studybymyself;

public class Test_continue {
	public static void main(String[] args) {
		int count = 0;
		outer : for(int i = 101;i<150;i++) {
			for(int j =2;j<i / 2;j++) {
				if(i%j==0) {
					continue outer;
				}
			}
			System.out.print(i+" ");
		}
	}
}

这里就是goto的影子的用法,其实是和我们递归的思想是很像的,ok说多了,我们接着说这递归的问题!那么既然找到问题的所在就要像怎么解决呢?想解决很简单,既然是他因为没有找到怎么结束我们告诉他怎么结束不就行了吗?是不是,所以我们其实可以直接给他加一个判断,告诉他,什么时候结束!

代码语言:javascript
复制
package com.gaojizu.studybymyself;
/**
 * 测试递归的思想
 *@author clearlove
 */

public class Test_Recursion {
	
	public static void test01() {
	   a++;
		System.out.println("test01"+a);
		if(a <= 10) {
			test01();
		}
		
	}
	public static void test02() {
		System.out.println("test02");
	}
	
	public static void main(String[] args) {
	    test01();
		
	}

}

我们告诉他,只要a的值大于10了,那么就停止!这样不就可以了吗?当然是可以的。

ok总结一下:怎么写一个完整的递归呢?它包含两部分,第一是递归头,第二是递归体

递归头就是什么时候不调自己的方法,如果没有就和之前的一样,陷入一个死循环

递归体就是什么时候调用自己的方法,如果没有就将毫无意义!

下面我们写一个比较经典的例子:阶乘

所谓的阶乘我们要明白是怎么回事!就是说8的阶乘就是8*(8-1)*(8-2)...(1)

我们看一下规律:这里的变量只有比他本身数值依次小一的数,那么其实用while或者for循环都是很简单的一个题目,这里我们用递归的思想写一个:

代码语言:javascript
复制
/**
 * 
 *测试递归   自己调用自己就是递归的思想
 *@author clearlove
 */
package com.gaojizu.studybymyself;

public class Test_Recursion {
	/**
	 * 
	 * @param n是形参的数值
	 * @return 阶乘的结果值
	 */
	public static long fact(int n) {
		if(n==1) {
			return 1;
		}else {
			return n*fact(n-1);
		}
	}
	public static void main(String[] args) {
		
		long sum = fact(5);
		System.out.println(sum);
	}

}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-10-07 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档