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.運行結果