一.实验目的
- 掌握递归程序设计的方法。明确递归的概念,通过对问题的分析,找出递归关系以及递归出口以对问题进行递归结构设计;
- 掌握递归程序转换为非递归程序的方法。
- 算法分析
用递归方法设计下列各题,并给出每道题目的递归出口(递归结束的条件)和递归表达式。同时考虑题目可否设计为非递归方法,如果可以,设计出非递归的算法。
1.一个人赶着鸭子去每个村庄卖,每经过一个村子卖去所赶鸭子的一半又一只。这样他经过了七个村子后还剩两只鸭子,问他出发时共赶多少只鸭子?经过每个村子卖出多少只鸭子?
(1)递归出口:n=0
(2)递归函数体:由a-(a/2+1)=剩余鸭子数,可得a=2*(剩余鸭子数+1),剩余鸭子数为最后一次鸭子个数,a为经过这个村子时鸭子数
a=(i+1)*2;
n=n-1;
if(n>0)
duck(a,n);
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)递归出口:n=1
(2)递归函数体:
if(n%2==0) //n为偶数
{
printf("%d\n",n/2);
++s;
return fun(n/2,s);
}
else //n为奇数
{
printf("%d\n",3*n+1);
++s;
return fun(3*n+1,s);
}
- 测试及运行结果
1.赶鸭子
测试代码:
void test(int counts){
int i = 1;
for (; i <= 7; i++){
counts = counts / 2 - 1;
}
if (counts == 2){
printf("测试正确,最后剩余%d只鸭子。\n", counts);
}
else{
printf("测试结果错误!\n");
}
}
2.角谷定理
测试代码:
void test(int num, int step)
{
int i = 1;
while (n > 1){
if (0 == n % 2){
i++;
n /= 2;
}
else{
i++;
n = n * 3 + 1;
}
}
if (i == step){
printf(“测试正确\n”);
}
四.源代码
//递归
#include<stdio.h>
//n为经过的村子个数,i为最后一次鸭子的个数
void duck(int i,int n){
int a; //经过第n-1个村子时鸭子的个数
a=(i+1)*2;
printf("经过第%d个村子卖出去%d只鸭子\n",n,a-i);
printf("一共有%d只鸭子\n",a);
n=n-1;
if(n>0)
duck(a,n);
}
int main(){
int num=7;
duck(2,7);
return 0;
}
//角谷定理
#include<stdio.h>
int fun(int n,int s)
{
if(n==1)
{
printf("STEP=%d\n",s);
return 1;
}
else
{
if(n%2==0) //n为偶数
{
printf("%d\n",n/2);
++s;
return fun(n/2,s);
}
else //n为奇数
{
printf("%d\n",3*n+1);
++s;
return fun(3*n+1,s);
}
}
}
int main()
{
int m,j=1;
printf("input an integer number:"); /*请输入一个整数*/
scanf("%d",&m);
fun(m,j);
return 0;
}
//非递归
#include<stdio.h>
//n为经过的村子数
int duck(n,s){
int a=2;
int i=0; //经过第n个村子时鸭子剩余个数
for(n;n>0;n--)
{
i=(a+1)*2;
printf("经过第%d个村子卖出去%d只鸭子\n",n,i-a);
printf("一共有%d只鸭子\n",i);
a=(a+1)*2;
}
return i;
}
int main(){
duck(7,2);
}
//角谷定理
import java.util.Scanner;
public class run {
static Scanner scanner=new Scanner(System.in);
public static int run(int x) {
int count=0;
while(1!=x) {//利用while循环,如果x不等于1则进行判断
if(x%2==0) {//如果能被2整除,偶数
x=x/2;//除2
}else {
x=3*x+1;//否则为奇数,*3+1
}
System.out.println("自然数"+x);
count=count+1; //次数+1
System.out.println("step="+count);
}
return count;
}
public static void main(String[] args) {
int x=scanner.nextInt();
run(x);
}