递归程序设计

一、题目分析

用递归方法设计下列各题,并给出每道题目的递归出口(递归结束的条件)和递归表达式。同时考虑题目可否设计为非递归方法,如果可以,设计出非递归的算法。
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塔问题),递归算法是一种自然且合乎逻辑的解决问题的方式,但是递归算法的执行效率通常比较差。因此,在求解某些问题时,常采用递归算法来分析问题,用非递归算法来求解问题;另外,有些程序设计语言不支持递归,这就需要把递归算法转换为非递归算法。
将递归算法转换为非递归算法有两种方法,一种是直接求值(迭代/循环),不需要回溯;另一种是不能直接求值,需要回溯。前者使用一些变量保存中间结果,称为直接转换法;后者使用栈保存中间结果,称为间接转换法。这是我在CSDN上看到的学习链接:https://blog.csdn.net/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);
	}

}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值