Java中递归和循环的优劣
介绍:
你用你手中的钥匙打开一扇门,结果去发现前方还有一扇门,紧接着你又用钥匙打开了这扇门,然后你又看到一扇门......但是当你开到一扇门时,发现前方是一堵墙无路可走了,你选择原路返回--这就是递归。
但是如果你打开一扇门后,同样发现前方也有一扇门,紧接着你又打开下一扇门.....但是却一直没有碰到尽头--这就是循环。
简单来说:循环是有去无回,而递归是有去有回(因为存在终止条件)。
循环:当满足某一条件时反复执行某一操作(循环体)。
递归:在一个方法内部对自身进行调用的方法。
递归结构包括两个部分:
1、递归头:即什么时候不调用自身方法,也就是递归的结束条件。如果没有递归头,程序将陷入死循环。
2、递归体:即什么时候需要调用自身方法。
好了,废话不多说,直接来撸代码(计算阶乘的方法)。
package com.bjwyj.method;
/**
* 递归和循环的比较
* @author 吴永吉
*
*/
public class TestRecursion {
public static void main(String[] args) {
//以下调用System下的currentTimeMillis()方法只是为了说明递归调用比循环调用更耗时
long l1 = System.currentTimeMillis();
System.out.println(factorial(5));
long l2 = System.currentTimeMillis();
System.out.println("递归计算阶乘耗时:"+(l2-l1)); System.out.println("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$");
long time1 = System.currentTimeMillis();
System.out.println(factorialLoop(5));
long time2 = System.currentTimeMillis();
System.out.println("循环计算阶乘耗时:"+(time2-time1));
} //使用递归定义计算阶乘的方法
public static long factorial(int num) {
if(num==1) { //递归头
return 1;
}else {
return num*factorial(num-1); //递归体
}
} //使用循环定义计算阶乘的方法
public static long factorialLoop(int n) {
int result = 1; //接收计算结果
while(n>1) {
result *= n*(n-1); //实现计算结果的累乘操作
n -= 2; //每次减去2,实现数字的迭代操作
}
return result;
}
}
执行结果:
120
递归计算阶乘耗时:1
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
120
循环计算阶乘耗时:0
由结果可以看出,使用递归算法比使用循环算法更耗时。
为了更好地比较递归算法的优劣,上述采用while循环与递归算法进行对比。
先来分析上述递归方法的执行过程,如下图:

循环方法的执行过程,如下图:

这里为了看起来清晰,只是简单地画出了栈内存中的执行过程(这样画更便于理解)。
总结:
栈,主要是用来存放栈帧的,每执行一个方法就会出现压栈操作,所以采用递归的时候产生的栈帧比较多,递归就会影响到内存,非常消耗内存。而使用循环就执行了一个方法,压入栈帧一次,只存在一个栈帧,所以比较节省内存。
Java中递归和循环的优劣的更多相关文章
- java 中递归的实现 以及利用递归方法实现汉诺塔
今天说下java语言中比较常见的一种方法,递归方法. 递归的定义 简单来说递归的方法就是"自己调用自己",通过递归方法往往可以将一个大问题简单化,最终压缩到一个易于处理的程度.对于 ...
- Java中的do-while循环——通过示例学习Java编程(11)
作者:CHAITANYA SINGH 来源:https://www.koofun.com/pro/kfpostsdetail?kfpostsid=22&cid=0 在上一篇教程中,我们讨论了w ...
- Java中的for循环——通过示例学习Java编程(9)
作者:CHAITANYA SINGH 来源:https://www.koofun.com/pro/kfpostsdetail?kfpostsid=21 循环用于反复执行同一组语句,直到满足特定条件 ...
- [转帖]java中的for循环
java中的for循环 https://baijiahao.baidu.com/s?id=1621622990642364099&wfr=spider&for=pc 发现自己连 for ...
- JAVA中的for-each循环与迭代
在学习java中的collection时注意到,collection层次的根接口Collection实现了Iterable<T>接口(位于java.lang包中),实现这个接口允许对象成为 ...
- Java中list在循环中删除元素的坑
JAVA中循环遍历list有三种方式for循环.增强for循环(也就是常说的foreach循环).iterator遍历. 1.for循环遍历list for(int i=0;i<list.siz ...
- Java中增强for循环的用法
此方法在jdk1.5之后才出现. 1:遍历数组 语法: for (Type value : array) { expression value; } 例子: void Sum() { int[] ar ...
- 关于java中的一些循环
1:switch语句 (1)格式: switch(表达式) { case 值1: 语句体1; break; case 值2: 语句体2; break; ... default: 语句体n+1; bre ...
- Java中递归的优缺点,Java写一个递归遍历目录下面的所有文件包括子文件夹里边的文件。
题目: 遍历出aaa文件夹下的文件 首先分析思路: 1.首先判断这个文件夹是否为文件,通过isFile()函数可以判断是否为文件. 2.然后通过isDirectory判断是否为目录. 3.如果是目录就 ...
随机推荐
- SRS服务器搭建,ffmpeg 本地推流,srs从本地拉流
参考: https://github.com/ossrs/srs/wiki/v2_CN_SampleFFMPEG git clone https://github.com/ossrs/srs cd s ...
- BackBone结合ASP.NET MVC实现页面路由操作
1. 问题的背景 什么是页面路由操作,就是通过浏览器地址栏的标记来实现页面内部的一些操作,这些操作具有异步性和持久性.应用场景主要有页面操作过程中的添加收藏夹的操作.后退操作等过程中能完全恢复界面. ...
- 深入分析Linux自旋锁【转】
转自:http://blog.chinaunix.net/uid-20543672-id-3252604.html 前言: 在复习休眠的过程中,我想验证自旋锁中不可休眠,所以编写了一个在自旋锁中休眠的 ...
- 用rand()和srand()产生伪随机数的方法总结 【转】
转自:http://blog.chinaunix.net/uid-26722078-id-3754502.html 标准库(被包含于中)提供两个帮助生成伪随机数的函数: 函数一:int rand(vo ...
- python3爬虫中文乱码之请求头‘Accept-Encoding’:br 的问题
当用python3做爬虫的时候,一些网站为了防爬虫会设置一些检查机制,这时我们就需要添加请求头,伪装成浏览器正常访问. header的内容在浏览器的开发者工具中便可看到,将这些信息添加到我们的爬虫代码 ...
- HTMl学习笔记02-编辑器
工欲善其事,必先利其器 使用专业HTML编辑器来编辑HTML,推荐使用Notepad++,中文界面. 在Notepad++安装完成后,点击文件>新建.语言>H中选择HTML 在新建的文件输 ...
- 017_nginx重定向需求
重定向的各种需求 需求一. 前端同事需要把特定的url进行重定向,实现如下: location / { root /data/base.apiportal_opsweb; index index.ht ...
- centos6.7环境之kvm虚拟化quem工具配置及使用详解
环境准备 需要勾选CPU的虚拟化支持,支持cpu虚拟化的CPU列表: intel支持虚拟化技术CPU列表: Intel 6 Cores / 12 Threads CPU Number: Code Na ...
- linux unzip 中文乱码解决方法
引自:https://blog.csdn.net/abyjun/article/details/48344379 unzip -O CP936 xxx.zip (用GBK, GB18030也可以)
- Python-JS (JS介绍~JS的基础数据类型)
目录一.JS语言介绍: 1.JS概念 2.JS组成 二.JS的三种存在位置(引入方式): 1.行间式: 2.内联式: 3.外联式: 三.JS出现的具体位置: 四.JS语法规范 五.JS中变量的定义 E ...