每日算法(三十六)-java递归

本文介绍了Java中递归的概念,包括递归的两个基本条件和递归与栈的关系。通过阶乘计算的例子详细阐述了递归的过程,并指出递归可以改写为非递归版本。此外,还讨论了兔子问题,展示了递归解决斐波那契数列的问题,提供了递归和非递归两种实现方式。

每日算法(三十六)-java递归

递归(recursion):程序调用自身的编程技巧。

递归满足2个条件:
1)有反复执行的过程(调用自身)
2)有跳出反复执行过程的条件(递归出口)
递归与栈的关系
下面演示的是求n的阶乘

int Factorial(int n){    
      if (n == 0)  return 1;  
      return  n * Factorial(n - 1);
}

常常听到 “递归的过程就是出入栈的过程”,这句话怎么理解?我们以上述代码为例,取 n=3,则过程如下:

第 1~4 步,都是入栈过程,Factorial(3)调用了Factorial(2),Factorial(2)又接着调用Factorial(1),直到Factorial(0);

第 5 步,因 0 是递归结束条件,故不再入栈,此时栈高度为 4,即为我们平时所说的递归深度;

第 6~9 步,Factorial(0)做完,出栈,而Factorial(0)做完意味着Factorial(1)也做完,同样进行出栈,重复下去,直到所有的都出栈完毕,递归结束。

每一个递归程序都可以把它改写为非递归版本。我们只需利用栈,通过入栈和出栈两个操作就可以模拟递归的过程,二叉树的遍历无疑是这方面的代表。

但是并不是每个递归程序都是那么容易被改写为非递归的。某些递归程序比较复杂,其入栈和出栈非常繁琐,给编码带来了很大难度,而且易读性极差,所以条件允许的情况下,推荐使用递归。
练习
有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第四个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少对?
这里我们可以先把情况列举出来查看规律,
第一个月 1
第二个月 1
第三个月 2
第四个月 3
第五个月 5
第六个月 8
不难发现从第三个月开始数量是前两个月的和,与上面的斐波那契数列非常像,代码如下

public static int add(int month){
	if(month==1|month==2){
		return 1 ;
	}else{
		return add(month-1)+add(month-2);
	}
}

非递归代码:

public static void addTwo(){
	int s1=1;
	int s2=1;
	for(int month=1;month<13;month++){
		if(month==1|month==2){
			System.out.println("第"+month+"月数量为:"+s2);
			continue;
		}else{
			int temp=s2; 
			s2=s1+s2;
			s1=temp;
			System.out.println("第"+month+"月数量为:"+s2);
		}
		}
}

练习二:十进制转二进制
递归代码

static String str="";  
public static int binary(int data) {     
    if(data%2!=0)
    {
        str="1"+str;
    }else {            
        str="0"+str;            
    }
    if (data/2==0) {            
        return 1;
    }        
    return 1+binary(data/2);     
}

非递归:

public static void transForm(int data){
	String str="";
	while(data!=0){   //
		str=data%2+str;  //余数  
		data=data/2;
	}
	System.out.println(str);
	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值