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.如果是目录就 ...
随机推荐
- aar jar包打包
使用Android Studio Module的方式编译出aar和jar包: aar包:打aar包时,gradle compile依赖编译进来的包不会被打到aar包中,所以接入aar的应用仍然需要添加 ...
- 实验一 Java开发环境的熟悉--20165221
实验报告封面 课程:Java程序设计 班级:1652班 姓名:谭笑 学号:20165221 成绩: 指导教师:娄嘉鹏 试验日期:2018.4.2 实验组次:21 预习程度:已预习 实验时间:15:35 ...
- 404错误处理以及以后缀为action结尾的处理
--------------第一种是胡乱敲,后缀不是以action结尾,出现404错误-----------------------------
- Informatic学习总结_day01
1.forlder 必须open之后才出现 mapping的界面 2.Source Qualifer 3.小技巧 验证自己写的转换格式是否正确 提前过滤一些数据,informatica工具的本质也是 ...
- linux matlab2016 安装
1. 下载Matlab 2016b 下载文件夹中包含三个文件:Matlab 2016b Linux64 Crack.rar,R2016b_glnxa64_dvd1.iso,R2016b_glnxa64 ...
- WPF复制异常问题(OpenClipboard 失败 (异常来自 HRESULT:0x800401D0 (CLIPBRD_E_CANT_OPEN)))
最近在维护WPF系统的时候发现的问题,刚刚开始自己的电脑都不能重现,后面写日志跟踪才发现问题的所在.问题主要是由于:1. 在程序访问剪切板的时候,有其他程序正在占用剪切板,导致自己的程序无法访问, ...
- C++ Boost库简介(转载)
boost是一个准标准库,相当于STL的延续和扩充,它的设计理念和STL比较接近,都是利用泛型让复用达到最大化.不过对比STL,boost更加实用.STL集中在算法部分,而boost包含了不少工具类, ...
- emmc基础技术8:操作模式2-device identification mode
1.前言 eMMC总线操作包含: boot mode, device identification mode interrupt mode data transfer mode 本文主要描述devic ...
- 简单解决“ORA-27100: shared memory realm already exists”的问题
背景 看到这篇文章,算是当初记录过程的一篇了,不像别的,只是有个结果算火.只是感觉到现在可能是碰不见这个问题了,现在哪有32位的oracle啊.可见技术随着岁月的变化,真不知10年后再看今天的问题,可 ...
- lvs持久连接及防火墙标记实现多端口绑定服务
lvs持久连接及防火墙标记实现多端口绑定服务 LVS持久连接: PCC:将来自于同一个客户端发往VIP的所有请求统统定向至同一个RS: PPC:将来自于一个客户端发往某VIP的某端口的所有请求统统定向 ...