Java 怎么使用java递归输出反向数字或者循环输出数字 1 到 5 的所有可能性组合?

Java中的迭代和递归详解_java
作者:用户
本文讲的是Java中的迭代和递归详解_java,
最近在看书的时候看到这一内容,感觉还是蛮有收获的。迭代使用的是循环(for,while,do...wile)或者迭代器,当循环条件不满足时退出。而递归,一般是函数递归,可以是自身调用自身,也可以是非直接调用,即方法A调用方法B,而方
最近在看书的时候看到这一内容,感觉还是蛮有收获的。迭代使用的是循环(for,while,do...wile)或者迭代器,当循环条件不满足时退出。而递归,一般是函数递归,可以是自身调用自身,也可以是非直接调用,即方法A调用方法B,而方法B反过来调用方法A,递归退出的条件为if,else语句,当条件符合基的时候退出。
上面是迭代和递归的语法特性,他们在Java中有什么不同呢?下面通过这篇来详细了解了解。
提到迭代,不得不提一个数学表达式: n!=n*(n-1)*(n-2)*...*1
有很多方法来阶乘。有一定数学基础的人都知道n!=n*(n-1)!因此,代码的实现可以直接写成:
int factorial (int n) {
if (n == 1) {
return n*factorial(n-1);
在执行以上代码的时候,其实机器是要执行一系列乘法的: factorial(n) → factorial(n-1) → factorial(n-2) → … → factorial(1) 。所以,需要不断的跟踪(跟踪上次计算的结果)并调用乘法进行计算(构建一个乘法链)。这类不断调用自身的运算形式称之为递归。递归可以进一步的分为线性递归和数形递归。信息量随着算法的输入呈线性增长的递归称之为线性递归。计算n!(阶乘)就是线性递归。因为随着N的增大,计算所需的时间呈线性增长。另外一种信息量随着输入的增长而进行指数增长的称之为树形递归。
另外一种计算n!的方式是:先计算1乘以2,然后用其结果乘以3,再用的到的结果乘以4….一直乘到N。在程序实现时,可以定义一个计数器,每进行一次乘法,计数器都自增一次,直到计数器的值等于N截至。代码如下:
int factorial (int n) {
int product = 1;
for(int i=2; i&n; i++) {
product *=
和代码一相比,代码二没有构建一个乘法链。在进行每一步计算时,只需要知道当前结果(product)和i的值就可以了。这种计算形式称之为迭代。迭代有这样几个条件:1、有一个有初始值的变量。2、一个说明变量值如何更新的规则。3、一个结束条件。(循环三要素:循环变量、循环体和循环终止条件)。和递归一样。时间要求随着输入的增长呈线性的可以叫做线性迭代。
三、迭代 VS 递归
比较了两个程序,我们可以发现,他们看起来几乎相同,特别是其数学函数方面。在计算n!的时候,他们的计算步数都是和n的值成正比的。但是,如果我们站在程序的角度,考虑他们是如何运行的话,那么这两个算法就有很大不同了。
(注:原文中关于其区别写的有点扯,这里就不翻译了,下面是笔者自己总结内容。)
首先分析递归,其实递归最大的有点就是把一个复杂的算法分解成若干相同的可重复的步骤。所以,使用递归实现一个计算逻辑往往只需要很短的代码就能解决,并且这样的代码也比较容易理解。但是,递归就意味着大量的函数调用。函数调用的局部状态之所以用栈来记录的。所以,这样就可能浪费大量的空间,如果递归太深的话还有可能导致堆栈溢出。
接下来分析迭代。其实,递归都可以用迭代来代替。但是相对于递归的简单易懂,迭代就比较生硬难懂了。尤其是遇到一个比较复杂的场景的时候。但是,代码的难以理解带来的有点也比较明显。迭代的效率比递归要高,并且在空间消耗上也比较小。
递归中一定有迭代,但是迭代中不一定有递归,大部分可以相互转换。
能用迭代的不要用递归,递归调用函数不仅浪费空间,如果递归太深的话还容易造成堆栈的溢出。
四、数形递归
前面介绍过,树递归随输入的增长的信息量呈指数级增长。比较典型的就是斐波那契数列:
用文字描述就是斐波那契数列中前两个数字的和等于第三个数字:0,1,1,2,3,5,8,13,21……
递归实现代码如下:
int fib (int n) {
if (n == 0) {
} else if (n == 1) {
return fib(n-1) + fib(n-2);
计算过程中,为了计算fib(5) ,程序要先计算fib(4) 和 fib(3) ,要想计算fib(4) ,程序同样需要先计算 fib(3) 和 fib(2) 。在这个过程中计算了两次fib(3)。
从上面分析的计算过程可以得出一个结论:使用递归实现斐波那契数列存在冗余计算。
就像上面提到的,可以用递归的算法一般都能用迭代实现,斐波那契数列的计算也一样。
int fib (int n) {
int fib = 0;
int a = 1;
for(int i=0; i&n; i++) {
int temp =
fib = fib +
虽然使用递归的方式会有冗余计算,可以用迭代来代替。但是这并不表明递归可以完全被取代。因为递归有更好的可读性。
以上就是这篇文章的全部内容了,希望本文的内容对大家学习或者使用Java能有所帮助,如果有疑问大家可以留言交流。
以上是云栖社区小编为您精心准备的的内容,在云栖社区的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索java
java迭代方法
java 迭代和递归、java递归算法详解、java递归调用详解、java递归详解、递归和迭代的区别,以便于您获取更多的相关知识。
稳定可靠、可弹性伸缩的在线数据库服务,全球最受欢迎的开源数据库之一
6款热门基础云产品6个月免费体验;2款产品1年体验;1款产品2年体验
弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率
开发者常用软件,超百款实用软件一站式提供
云栖社区()为您免费提供相关信息,包括
,所有相关内容均不代表云栖社区的意见!怎样利用循环递归算法列出一个数组里的全部数组合?
比如1 2列出来为1,2,12,21。
09-09-07 &匿名提问
先序非递归算法 【思路】 假设:T是要遍历树的根指针,若T != NULL 对于非递归算法,引入栈模拟递归工作栈,初始时栈为空。 问题:如何用栈来保存信息,使得在先序遍历过左子树后,能利用栈顶信息获取T的右子树的根指针? 方法1:访问T-&data后,将T入栈,遍历左子树;遍历完左子树返回时,栈顶元素应为T,出栈,再先序遍历T的右子树。 方法2:访问T-&data后,将T-&rchild入栈,遍历左子树;遍历完左子树返回时,栈顶元素应为T-&rchild,出栈,遍历以该指针为根的子树。 【算法1】 void    PreOrder(BiTree T, Status ( *Visit ) (ElemType e)) {    // 基于方法一 InitStack(S); while ( T!=NULL || !StackEmpty(S)){ while ( T != NULL ){ Visit(T-&data) ; Push(S,T); T = T-& } if( !StackEmpty(S) ){ Pop(S,T); T = T-& } } } 【算法2】 void    PreOrder(BiTree T, Status ( *Visit ) (ElemType e)) {    // 基于方法二 InitStack(S); while ( T!=NULL || !StackEmpty(S) ){ while ( T != NULL ){ Visit(T-&data); Push(S, T-&rchild); T = T-& } if ( !StackEmpty(S) ){ Pop(S,T); } } } 进一步考虑:对于处理流程中的循环体的直到型、当型+直到型的实现。 中序非递归算法 【思路】 T是要遍历树的根指针,中序遍历要求在遍历完左子树后,访问根,再遍历右子树。 问题:如何用栈来保存信息,使得在中序遍历过左子树后,能利用栈顶信息获取T指针? 方法:先将T入栈,遍历左子树;遍历完左子树返回时,栈顶元素应为T,出栈,访问T-&data,再中序遍历T的右子树。 【算法】 void    InOrder(BiTree T, Status ( *Visit ) (ElemType e)) {    InitStack(S); while ( T!=NULL || !StackEmpty(S) ){ while ( T != NULL ){ Push(S,T); T = T-& } if( !StackEmpty(S) ){ Pop(S, T); Visit(T-&data); T = T-& } } } 进一步考虑:对于处理流程中的循环体的直到型、当型+直到型的实现。 后序非递归算法 【思路】 T是要遍历树的根指针,后序遍历要求在遍历完左右子树后,再访问根。需要判断根结点的左右子树是否均遍历过。 可采用标记法,结点入栈时,配一个标志tag一同入栈(0:遍历左子树前的现场保护,1:遍历右子树前的现场保护)。 首先将T和tag(为0)入栈,遍历左子树;返回后,修改栈顶tag为1,遍历右子树;最后访问根结点。 [Page] typedef struct stackElement{ Bitree     char         }stackElemT 【算法】 void    PostOrder(BiTree T, Status ( *Visit ) (ElemType e)) {   InitStack(S); while ( T!=NULL || !StackEmpty(S) ){ while ( T != NULL ){ Push(S,T,0); T = T-& } while ( !StackEmpty(S) && GetTopTag(S)==1){ Pop(S, T); Visit(T-&data); } if ( !StackEmpty(S) ){SetTopTag(S, 1);        // 设置栈顶标记 T = GetTopPointer(S);   // 取栈顶保存的指针 T = T-&}}}
请登录后再发表评论!相关文章推荐
1.斐波那契数列递归实现
long long* MyFib(size_t n)
long long* FibArray=new ...
问题描述:
有形如 1,1,2,3,5,8,13,21,34...的数列,从第三项开始的结果为前两项之和,称作斐波拉切数列,即f(0) =0,
f(1) =1;f(n...
问题陈述:
前半篇转载地址:http://blog.csdn.net/woshisap/article/details/7566946
斐波那契数列,但凡学过编程的童鞋们应该都懂,背景就不介绍了(就是大兔...
《递归入门》
斐波那契数列百度百科
斐波那契数列指的是这样一个数列:0、1、1、2、3、5、8、13、21、……
在数学上,斐波纳契数列以如下被以递归的方法定义:F0=0,F1=1,Fn=F(n...
int n = 0;
void swap(int &a, int &b)
用Stack或LinkedList来实现内存中的出栈入栈过程,即可将递归改成循环。
第一个例子用求阶乘,顺便加了迭代方法。
import java.util.S
public class...
//int j=0;
private void xuhao() {
for (int j = 0; j
System.out.println("请输入第" + (j+1) + "辆车的序号:");
java之递归循环与递归1.程序调用自身的编程技巧称为递归( recursion)。递归做为一种算法在程序设计语言中广泛应用。 一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一...
他的最新文章
他的热门文章
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)相关文章推荐
利用递归实现不定重数多重循环(附源代码)  很多情况下我们要实现的程序本身并不复杂但却很烦琐,这里举一个穷举的例子。多数穷举程序需要遍历多个循环点,我们遇到的情况经常是:变量a的变化范围是aMin~a...
定义:程序调用自身的编程技巧称为递归。
栈与递归的关系:递归是借助于系统栈来实现的。每次递归调用,系统都要为该次调用分配一系列的栈空间用于存放此次调用的相关信息:返回地址,局部变量等。当调用...
【 声明:版权所有,欢迎转载,请勿用于商业用途。
联系信箱:feixiaoxing @】
其实编程的朋友知道,不管学什么语言,循环和递归是两个必须学习的内容。当然,如...
1.在JAVA中如何跳出当前的多重嵌套循环
在java中,要想跳出多重循环,可以在外面的循环语句前定义一个标号,然后在里层循环体的代码中使用带有标号的的break语句,即可跳出
外层循环。例如:
一、标号方式
在Java中,要想跳出多重循环,可以在外面的循环语句前定义一个标号,然后在里层循环体的代码中使用带有标号break语句,即可跳出外层循环。例如:ok:
for(int i=0;i...
递归本来要来简化循环问题的,不过程序中往往却有for加递归一起使用的情况。我们在for里面堪套for,或者for里面的for再堪套for,都能很直观地理解。当for里面加入了递归,理解的层面就由三维跳...
先说开发环境,我们是OSGI环境,使用的是struts2自带的OSGI插件的环境(当然了,我们对该插件做了升级,Struts2自带的插件支持felix版本比较低)。在解决项目问题时需要对系统中的一些对...
递归嵌套解析,较复杂的json串
这里的n是不确定的。
实现的功能描述如下:1.
有一个字符串的矩阵,用vector > 表示2.
行与行之间进行排列组合3.
他的最新文章
他的热门文章
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)标签:至少1个,最多5个
微博上看到这么一个问题: 原文都是C++的版本,我用Java实现了一种,是根据定时器实现的。其实还可以用线程+函数,懒得写了,先贴出定时器版本吧。
public static void main(String args[]){
final Timer timer = new Timer();
final long delay = 1;
Date date = new Date();
timer.schedule(new TimerTask() {
int num = 1;
public void run() {
System.out.println(num++);
if (num == 0x65){
timer.cancel();
}, date, delay);
0 收藏&&|&&0
你可能感兴趣的文章
4 收藏,429
20 收藏,1.1k
6 收藏,1.4k
分享到微博?
我要该,理由是:

我要回帖

更多关于 java递归输出反向数字 的文章

 

随机推荐