【C++】(递归+非递归)卖鸭子及角谷定理+递归模型+递归树

本文详细探讨了使用C++编程解决卖鸭子问题和角谷定理的递归与非递归方法。针对卖鸭子问题,通过递归模型和递归树展示了如何计算出发时鸭子的数量。同时,文章解释了角谷定理,阐述了如何递归地计算达到自然数1所需的步骤。

ps:全文中如果有任何错误您看到并能指出来的话(尤其是递归树)感激不尽XDDDD

每个问题包含:

(1)题目描述(2)递归解决代码(3)非递归解决代码(4)递归模型(5)递归树(6)运行结果截图


一、卖鸭子问题

1.题目描述

       一个人赶着鸭子去每个村庄卖,每经过一个村子卖去所赶鸭子的一半又一只。这样他经过了七个村子后还剩两只鸭子,问他出发时共赶多少只鸭子?经过每个村子卖出多少只鸭子?

2.递归解决代码(解释见代码)

/*
   @Author:Innocence
   @IDE:dev C++
   @OS:win10
   @Time:2019/5/30
   @Edition:1.0
   @Description:【递归解决】已知剩下的鸭子和卖鸭子的规则求一开始的鸭子数及每个村庄卖的鸭子 
*/

#include<iostream>
using namespace std;
int sale(int left_duck,int flag)
{   // 倒推过程 
	int sale_duck=(left_duck+1)*2-left_duck;   // 卖出的鸭子数=(剩下的鸭子数+1)*2[即原本的鸭子数]-剩下的鸭子数 
	int duck=sale_duck+left_duck;   // 原本的鸭子数=剩下的+卖出的 
	flag-=1;     // 因为是倒推所以村落数递减 
	if(flag<0)   // 递归出口。且不能等于0,因为一开始就减一了,如果等于0实际相当于只去了6个村子 
	{
		return left_duck;   // 返回此时鸭子数,即最开始的鸭子数 
	}
	else
	{
		cout<<"在第"<<flag+1<<"个村子卖出"<<sale_duck<<"只鸭子"<<endl;   
		duck=sale(duck,flag);   // 本级递归处理、调用。继续倒退卖鸭子 
	}
}

int main()
{
	int left_duck=2;   // 最后剩下的鸭子数 
	int duck=sale(left_duck,7);   // 剩下的鸭子数,去过的7个村庄 
	cout<<endl<<"原本有"<<duck<<"只鸭子(在第一个村子时)"<<endl;
	return 0;
}

3.非递归解决代码(解释见代码)

/*
   @Author:Innocence
   @IDE:dev C++
   @OS:win10
   @Time:2019/5/30
   @Edition:1.0
   @Description:【非递归解决】用for循环代替递归
*/

#include<iostream>
using namespace std;
int sale(int left_duck)
{   // 倒推过程 
	int duck=(left_duck+1)*2;   // 原本的鸭子数=剩下的+卖出的 
	return duck;
}

int main()
{	
	int duck=0;        // 原本的鸭子数 
	int left_duck=2;   // 最后剩下的鸭子数 
	int sale_duck=0;   // 卖掉的鸭子数
	for(int i=1;i<=7;i++)
	{ 
		duck=sale(left_duck);       // 这个村庄此时的鸭子数 
		sale_duck=duck-left_duck;   // 卖出的鸭子数=原本的鸭子数-剩下的鸭子数 
		left_duck=duck;             // 经过这个村庄后剩下的鸭子数等于此时的鸭子数 
		cout<<"在第"<<8-i<<"个村子卖出"<<sale_duck<<"只鸭子(在第一个村子)"<<endl;  
	}
	cout<<endl<<"原本有"<<duck<<"只鸭子"<<endl;
	return 0;
}

4.递归模型

【模板】

递归函数(){ 1、递归的出口; 2、递归调用 3、递归的本级处 }

【此题的递归模型】

递归函数:int sale(int left_duck,int flag) { 1.递归的出口:flag<0  2.递归调用、递归的本级处  duck=sale(duck,flag); }

5.递归树

6.运行结果

二、角谷定理

1.题目描述

       输入一个自然数,若为偶数,则把它除以2,若为奇数,则把它乘以3加1。经过如此有限次运算后,总可以得到自然数值1。求经过多少次可得到自然数1。

如:输入22,

输出 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1       STEP=16

2.递归解决代码(解释见代码)

/*
   @Author:Innocence
   @IDE:dev C++
   @OS:win10
   @Time:2019/5/30
   @Edition:1.0
   @Description:【递归解决】角谷定理的应用 
*/
#include<iostream>
using namespace std;

//角谷定理函数 
int Theorem(int num,int step)
{
	if(num==1)
		return step;   // 返回执行的步数 
	if(num%2==0)
	{
		num=num/2;     // 是偶数就除以2 
		cout<<" -> "<<num;
		step+=1;       // 执行步数+1 
		num=Theorem(num,step);   // 本级递归处理、调用 
	}
	else 
	{
		num=num*3+1;   // 是奇数就乘三再加一 
		cout<<" -> "<<num;
		step+=1;       // 执行步数+1
		num=Theorem(num,step);   // 本级递归处理、调用 
	}
}
int main()
{
	int num;   
	int step;
	cout<<"请输入一个自然数:"<<endl; 
	cin>>num;     //输入一个整数 
	cout<<num;    //为了输出美观 
	step=Theorem(num,1);
	cout<<endl<<endl<<"共用了"<<step<<"步"<<endl;
	return 0;
} 

3.非递归解决代码(解释见代码)

/*
   @Author:Innocence
   @IDE:dev C++
   @OS:win10
   @Time:2019/5/30
   @Edition:1.0
   @Description:【非递归解决】实际就用一个while循环代替递归  角谷定理的应用 
*/
#include<iostream>
using namespace std;

int main()
{
	int num;   
	int step=1;
	cout<<"请输入一个自然数:"<<endl; 
	cin>>num;     //输入一个整数 
	cout<<num;    //为了输出美观 
	while(1)
	{
		if(num==1)         // num为1就退出循环 
			break;
		else if (num%2==0)   
		{
			num=num/2;     // 是偶数就除以2 
			cout<<" -> "<<num;
			step+=1;       // 执行步数+1 
		}
		else if (num%2!=0)
		{
			num=num*3+1;   // 是奇数就乘三再加一 
			cout<<" -> "<<num;
			step+=1;       // 执行步数+1
		}
	}
	cout<<endl<<endl<<"共用了"<<step<<"步"<<endl;
	return 0;
} 

4.递归模型

【模板】

递归函数(){ 1、递归的出口; 2、递归调用 3、递归的本级处 }

【此题的递归模型】

递归函数:int Theorem(int num,int step) { 1.递归的出口:num==1  2.递归调用、递归的本级处  num=Theorem(num,step);}

5.递归树

6.运行结果

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值