一.实验目的
1.掌握递归程序设计的方法。明确递归的概念,通过对问题的分析,找出递归关系以及递归出口以对问题进行递归结构设计;
2.掌握递归程序转换为非递归程序的方法。
二.实验内容
用递归方法设计下列各题,并给出每道题目的递归出口(递归结束的条件)和递归表达式。同时考虑题目可否设计为非递归方法,如果可以,设计出非递归的算法。
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
三.实验分析
题目一
递归:经过第n个村子时的鸭子数等于上一个村子剩下的鸭子数rest(n),由于经过第七个村子时鸭子只剩两只了,所以rest(7)=2,rest(0)为鸭子的总数,也可以知道在第n个村子的鸭子数为(rest(n-1)/2+1)。这是由rest(n)-rest(n-1)=rest(n)/2+1得出。
非递归:一共有七个村子,在第七个村子只剩2只鸭子,可以推出上一个村子有几只鸭子,所以可以通过一个for循环来求出每个村子没卖之前的鸭子数。也可求出每个村子卖了多少只鸭子,进而可以求出每个村子剩下的鸭子数。
题目二
递归:我用了fun(int n,int i)递归函数,其中n是传入的自然数,i是记录步数。
将i设为1,因为算了自然数本身。当n为1时,输出1,当n为偶数时,输出n/2,并再次进入递归函数,当n为奇数时,输出n*3+1,并再次进入递归函数。
非递归:通过for循环来控制条件以及步数,然后用if-else语句来实现每一次结果的输出。
四.运行结果
题目一
题目二
五 . 源代码
题目一
//递归
#include<stdio.h>
int rest(int i){
if(i==7)//递归出口
return 2;
else
return (rest(i+1)+1)*2;
}
int sell()
{
for(int i=1;i<=7;i++)
{
printf("经过第%d个村庄时,卖了%d只鸭子,还剩鸭子数:%d\n",i,(rest(i-1)/2+1),rest(i));
}
return 0;
}
void main()
{
printf("鸭子的总数为:%d\n", rest(0));
sell();
}
//非递归
#include<stdio.h>
int main(void)
{
int x;
int y=2;
for(int i=7;i>0;i--)
{
y=(y+1)*2;
}
for(int j=1;j<=7;j++)
{
printf("第%d村子有%d只鸭子",j,y);
x=y/2+1;
y=y-x;
printf("卖了%d只鸭子,还剩鸭子数:%d\n",x,y);
}
return 0;
}
题目二
//递归
#include<iostream>
using namespace std;
int fun(int x,int i)
{
if(x==1)//递归出口
{
cout<<endl<<"Step="<<i<<endl;
return 1;
}
else if(x%2==0)
{
cout<<x/2<<" ";
i=i+1;
return fun(x/2,i);
}
else
{
cout<<x*3+1<<" ";
i=i+1;
return fun(x*3+1,i);
}
}
void main()
{
int a,b=1;
cout<<"请输入一个自然数:"<<endl;
cin>>a;
cout<<a<<" ";
fun(a,b);
}
//非递归
#include<iostream>
using namespace std;
int main(void)
{
int x,i;
cout<<"请输入一个自然数:"<<endl;
cin>>x;
if(x==1)
{
cout<<"Step=1"<<endl;
}
else {
for(i=1;x!=1;i++)
{
if(x%2==0)
{
x/=2;
cout<<x<<" ";}
else
{
x=x*3+1;
cout<<x<<" "; }
}
}
cout<<endl;
cout<<"Step="<<i<<endl;
return 0;
}