java 什么时候用递归_如果要用Java实现算法,一定慎用递归

现象 :

递归是我们很经典的一种算法实现,可以很好的描述一个算法的原理!对于算法的描述、表现和代码结构理解上,递归都是不错的选择!

但是本文想说的是java实现一个递归算法的时候尽量不要用递归实现,而是转换成的非递归实现。

最近在实现一个比较复杂算法的时候,尝试了一下,非递归实现相比递归实现速度上能提升1/3。

以下面一个简单的例子来说:(注:为了描述简单,所以这里只用一个简单的例子)

输入参数:N

输出结果:log1+log2+log3+....+logN

两种实现代码如下:

Java代码

packagetest;

publicclassRecursiveTest {

/**

* 递归实现

*

* @param n

* @return

*/

publicstaticdoublerecursive(longn) {

if(n ==1) {

returnMath.log(1);

}else{

returnMath.log(n) + recursive(n -1);

}

}

/**

* 非递归实现

*

* @param n

* @return

*/

publicstaticdoubledirectly(longn) {

doubleresult =0;

for(inti =1; i <= n; i++) {

result += Math.log(i);

}

returnresult;

}

publicstaticvoidmain(String[] args) {

inti =5000000;

longtest = System.nanoTime();

longstart1 = System.nanoTime();

doubler1 = recursive(i);

longend1 = System.nanoTime();

longstart2 = System.nanoTime();

doubler2 = directly(i);

longend2 = System.nanoTime();

System.out.println("recursive result:"+ r1);

System.out.println("recursive time used:"+ (end1 - start1));

System.out.println("non-recursive result:"+ r2);

System.out.println("non-recursive time used:"+ (end2 - start2));

}

}

得到运行结果如下:

recursive result:7.212475098340103E7

recursive time used:539457109

non-recursive result:7.212475098340103E7

non-recursive time used:282479757

可以看出递归的运行时间是非递归运行时间将近2倍。

(注:以上代码还是在-Xss200m的参数下运行的,如果栈空间不足,直接不能运行)

原因简单分析:

9058803c38cbfbd35c652853c68cf313.png

上图是java线程栈的结构。java将为每个线程维护一个堆栈,堆栈里将为每个方法保存一个栈帧,栈帧代表了一个方法的运行状态。 也就是我们常说的方法栈。最后一个为当前运行的栈帧。

那么每一次方法调用会涉及:

1. 为新调用方法的生成一个栈帧

2. 保存当前方法的栈帧状态

3. 栈帧上下文切换,切换到最新的方法栈帧。

递归实现将导致在栈内存的消耗(往往需要调整Xss参数)和因为创建栈帧和切换的性能开销,最终大大的影响效率!

所以,如果你想提升你的算法效率,不要使用递归实现是一个基础原则!

另外,递归是我们用来理解算法的一个方法,当用代码来实现的时候基本都可以转换成非递归的代码实现!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/340834.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

excel分两个独立窗口_Excel2010 多个独立窗口,解决单窗口无法显示多个文件的问题...

当我们需要编辑多个excel的时候&#xff0c;就会发现一个问题&#xff0c;Excel不能一个窗口下显示多个文档&#xff0c;每次编辑都进行切换就太麻烦了&#xff0c;那如何能解决这个问题呢&#xff1f;接下来跟我一起看看吧&#xff01;首先在开始菜单输入regedit.exe命令&…

excel冻结窗口_excel怎么冻结窗口?excel冻结窗口怎么设置?

excel冻结行或列的技巧教程&#xff1a;一、冻结第一列1.选择 视图 > 冻结窗格 > 冻结第一列。2.列A和列B之间出现的细线表明第一列已冻结。二、冻结前两列1.选择第三列。2.选择 查看 > 冻结窗格 > 冻结窗格。三、冻结列和行1.选择要在滚动时保持可见的行下方和列右…

web service接口_win7 添加环回网卡+H3C 模拟器 防火墙开启Web功能

1、按下win R键&#xff0c;在其中输入&#xff1a;hdwwiz&#xff0c;然后点击“确定”或者按回车键&#xff0c;打开“添加硬件”对话框。2、看到如下界面时&#xff0c;选择“网络适配器”(如下图所示)&#xff0c; 在接着出现的界面中&#xff0c;左方“厂商”一栏里选择“…

java 实现nfa的化简_DFA与NFA的等价性,DFA化简

等价性对于每个NFA M存在一个DFA M’&#xff0c;使得L(M)L(M’)--------等价性证明&#xff0c;NFA的确定化假定NFA M&#xff0c;我们对M的状态转换图进行以下改造&#xff1a;解决初始状态唯一性&#xff1a;引进新的初态结点X和终态结点Y&#xff0c;X,Y∉S&#xff0c;从X…

eclipse查看git地址_gitamp;github的入门实战

一、Git概述&#xff08;1&#xff09;定义Git是目前世界上最先进的分布式版本控制系统。&#xff08;2&#xff09;能干什么&#xff1f;解决冲突、管理权限、代码备份、协同开发、版本还原、历史追查、版本记录、分支管理、代码审查&#xff08;3&#xff09;集中管理型版本管…

使用Apache Kafka作为消息系统的发布-订阅通信中的微服务,并通过集成测试进行了验证...

发布-订阅消息系统在任何企业体系结构中都起着重要作用&#xff0c;因为它可以实现可靠的集成而无需紧密耦合应用程序。 在解耦的系统之间共享数据的能力并不是一个容易解决的问题。 考虑一个企业&#xff0c;其中具有使用不同语言和平台独立构建的多个应用程序。 它需要以响应…

LINUX系统无线网频繁断开_Ubuntu系统安装amp;amp;解决WiFi不可用

写系统安装的文章太多太多了&#xff0c;我为何还要写哪&#xff1f; 因为文章太多太多了&#xff0c;乍一看各种操作猛如虎&#xff0c;实际上可能对你没有一点的帮助。好多文章只是讲解了如何安装ubuntu系统&#xff0c;对于安装后遇到的问题只字不提&#xff0c;笔者决定写一…

return两个返回值_LeetCode 第四题 寻找两个有序数组的中位数

给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。请你找出这两个有序数组的中位数&#xff0c;并且要求算法的时间复杂度为 O(log(m n))。你可以假设 nums1 和 nums2 不会同时为空。示例 1:nums1 [1, 3]nums2 [2]​则中位数是 2.0示例 2:nums1 [1, 2]nums2 [3, 4]​则中…

intellij 使用_使用IntelliJ书签

intellij 使用这是有关IntelliJ的精美书签功能的快速帖子。 IntelliJ使您可以为单行代码添加书签。 将某行添加为书签后&#xff0c;您可以使用多种方法直接跳回该行。 因此&#xff0c;最好在您经常使用的代码位置添加书签。 要创建一个新书签&#xff0c;只需在代码编辑器中…

[即将举行的网络研讨会]对Kubernetes进行故障排除:您需要具备的7个关键组件

如果您没有听说过&#xff0c;那么容器正在吞噬整个世界。 这种转变正在改变我们在开发&#xff0c;交付和维护应用程序方面所知的一切&#xff0c;尤其是在解决错误方面。 有这么多动人的东西&#xff0c;让您难以发现潜伏在基于Kubernetes的应用程序中的关键问题。 传统的故…

php能打开.shp文件吗,shp文件是什么格式的

shape文件由ESRI开发&#xff0c;一个ESRI的shape文件包括一个主文件&#xff0c;一个索引文件&#xff0c;和一个dBASE表。其中主文件的后缀就是【.shp】。本文操作环境&#xff1a;Windows7系统&#xff0c;Dell G3电脑。shape文件由ESRI开发&#xff0c;一个ESRI(Environmen…

成为Java流大师–第5部分:将联接的数据库表转换为流

是否可以将联接的数据库表转换为Java Stream&#xff1f; 答案是肯定的。 既然我们已经多次提出这个问题&#xff0c;我们决定写另一篇动手实验文章&#xff0c;解释如何执行更高级的Stream Joins。 因此&#xff0c;这里是第六篇中的第五篇&#xff0c;后面还有一个GitHub存储…

mysql数据库java链接,java链接MySQL数据库方法

第一步&#xff1a;安装MySQL这步我就很少说了&#xff0c;点击去看看怎么安装吧。html第二步&#xff1a;建立数据库安装好以后&#xff0c;咱们来建立一个数据库&#xff0c;一个表。(代码以下)。//建立数据库 test&#xff1b;//在数据库中建立表 user//插入一条数据create …

matlab虚线分格线,虚线实线网格线……一分钟看懂路面标志线,不再被扣分!

黄色实线黄色实线用来区分不同方向的车道&#xff0c;一般画在马路正中间&#xff0c;车道多的路面上就是双黄线&#xff0c;车道少的路面上则用单黄线。而无论单黄线还是双黄线&#xff0c;均严格禁止车辆跨越&#xff0c;因此压线行驶、超车或者掉头等都是不允许的。黄色虚线…

python 判断列表为空_Python 判断列表为空

原博文 2020-06-05 12:38 − https://mp.weixin.qq.com/s?__bizMzU2MDQwOTU0MA&mid2247483845&idx1&sndaf1d3661b4e6b6a15dbe40c7f9c0e14&chksmfc093f6ecb7eb678c22e3... 相关推荐 2019-09-28 21:13 − Python python是一种跨平台的计算机程序设计语言&#x…

clodeblocks debug断点调试_idea debug调试————简单常用,适合初学者

背景&#xff1a;在现在的开发中&#xff0c;如果不会debug&#xff0c;那么将会给我们的开发带来很大的困扰&#xff0c;如果仅仅是依靠日志信息去查问题&#xff0c;将会大大增加我们解决问题的难度&#xff0c;下面说一下idea开发工具下的简单debug。适用人群&#xff1a;ja…

bigdecimal判断等于0_vue2.0源码用到的工具函数,12个简易的复用函数,看看有多简单...

戎马&#xff1a;https://segmentfault.com/a/11900000196796381. 创建一个被冻结的空对象export const emptyObject Object.freeze({ }) 一旦创建不能给这个对象添加任何属性。2. 判断是否是 undefined 或 nullfunction isUndef (v) { return v undefined || v null}在源码…

告诉我们您想要什么,我们将做到:消费者驱动的合同测试消息传递

相当早以前&#xff0c;我们从REST&#xff08;ful&#xff09; Web API的角度讨论了消费者驱动的合同测试 &#xff0c;尤其是将其投射到Java&#xff08; JAX-RS 2.0规范&#xff09;的角度。 可以公平地说&#xff0c;至少在公共API方面&#xff0c; REST仍在Web API领域占据…

宝塔面板php降级,宝塔面板6.8.8降级到5.9.1的方案教程

有朋友问起&#xff0c;6.8版本用的不习惯&#xff0c;而且缺少5.9版本的nginx过滤器&#xff0c;而且6.8版本许多功能阉割的厉害&#xff1a;服务器状态中的 连接管理、进程管理 也都被阉割&#xff0c;5.9版本是可以在面板中查看服务器进程管理的&#xff0c;如图&#xff1a…

c++矩阵连乘的动态规划算法并输出_「Javascript算法设计」× 动态规划与回溯算法...

目录&#xff1a;分而治之算法动态规划回溯算法分而治之算法分而治之算法是算法设计的一种方式&#xff0c;它将一个问题分成多个和原问题相似的小问题&#xff0c;递归解决小问题&#xff0c;再将解决方式合并以解决原来的问题&#xff08;例如快速排序&#xff0c;二分搜索等…