一、题目分析
用递归方法设计下列各题,并给出每道题目的递归出口(递归结束的条件)和递归表达式。同时考虑题目可否设计为非递归方法,如果可以,设计出非递归的算法。
1.一个人赶着鸭子去每个村庄卖,每经过一个村子卖去所赶鸭子的一半又一只。这样他经过了七个村子后还剩两只鸭子,问他出发时共赶多少只鸭子?经过每个村子卖出多少只鸭子?
2.角谷定理。输入一个自然数,若为偶数,则把它除以2,若为奇数,则把它乘以3加1。经过如此有限次运算后,总可以得到自然数值1。求经过多少次可得到自然数1。
如:输入22,
输出 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
STEP=16
二、算法构造
1.第一题
2.第二题
三、调试
1.第一题
2.第二题
四、运行结果
递归
1.第一题
2.第二题
非递归
1.第一题
2.第二题
五、总结
1.递归算法转换为非递归算法
递归算法实际上是一种分而治之的方法,它把复杂问题分解为简单问题来求解。对于某些复杂问题(例如hanio塔问题),递归算法是一种自然且合乎逻辑的解决问题的方式,但是递归算法的执行效率通常比较差。因此,在求解某些问题时,常采用递归算法来分析问题,用非递归算法来求解问题;另外,有些程序设计语言不支持递归,这就需要把递归算法转换为非递归算法。
将递归算法转换为非递归算法有两种方法,一种是直接求值(迭代/循环),不需要回溯;另一种是不能直接求值,需要回溯。前者使用一些变量保存中间结果,称为直接转换法;后者使用栈保存中间结果,称为间接转换法。这是我在优快云上看到的学习链接:https://blog.youkuaiyun.com/fbz123456/article/details/50959412
2.递归算法解决问题的特点:
1)递归就是方法里调用自身。
2)在使用递增归策略时,必须有一个明确的递归结束条件,称为递归出口。
3)递归算法解题通常显得很简洁,但递归算法解题的运行效率较低。
4)在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储。
3.学习心得
学习递归程序设计,首先应该从小规模的递归开始研究,小规模就是说自己可以调试跟踪代码,且自己不会晕。这个过程完成之后,才能熟练掌握递归层次之间的转换,明白递归的执行过程。
六、源代码
package di_gui;
public class One {
private static int num(int m) {
if (m > 0) {
m--;
int temp = (num(m) + 1) * 2;
System.out.println("在倒数第" + (m + 1) + "个村庄时,有" + temp + "只鸭子,"
+ "卖出" + (temp - (temp / 2 - 1)) + "只鸭子");
return temp;
} else {
return 2;
}
}
public static void main(String[] args) {
System.out.println("一个赶了" + num(7) + "只鸭子");
}
}
package di_gui;
import java.util.Scanner;
public class Two {
private static int num(int n,int count){
if(n==1){
System.out.println();
System.out.println("经过"+count+"次,得到自然数1");//输出次数
return 1;
}
if(n%2==0){//当n是偶数时奇数
count++;
System.out.print(n/2+" ");
return num(n/2,count);
}else{//当n是奇数时
count++;
System.out.print(n*3+1+" ");
return num(n*3+1,count);
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
num(n,1);
}
}
package fei_di_gui;
public class One {
private static int num() {
int m = 7, n = 2;
for (int i = 0; i < m; i++) {
n = (n + 1) * 2;
System.out.println("在倒数第" + (i + 1) + "个村庄时,有" + n + "只鸭子,卖出"
+ (n - (n / 2 - 1)) + "只鸭子");
}
return n;
}
public static void main(String[] args) {
System.out.println("出发时共赶了" + num() + "只鸭子");
}
}
package fei_di_gui;
import java.util.Scanner;
public class Two {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int count = 1;
int n = sc.nextInt();
while (n != 1) {
if (n % 2 == 0) {
count++;
n = n / 2;
System.out.print(n + " ");
} else {
count++;
n = n * 3 + 1;
System.out.print(n + " ");
}
}
System.out.println();
System.out.println(count);
}
}