递归函数——习题

本文探讨了递归程序设计方法,包括递归概念的理解、递归关系的确定及递归出口的设计。通过卖鸭子问题和角谷定理两个实例,详细解析了递归算法的实现过程,并讨论了其转换为非递归算法的可能性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.实验目的

a.掌握递归程序设计的方法。明确递归的概念,通过对问题的分析,找出递归关系以及递归出口以对问题进行递归结构设计;

b.掌握递归程序转换为非递归程序的方法。

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

3.需求分析

1.卖鸭子问题

    A.倒推:经过7个村子后,剩余两只鸭子,则第八个村庄卖出2只,剩余d=0=(t=2)/2+1;

    B.第七个村庄则剩余d=2=t/2+1;t=6;所以在经过第七个村庄时共有6只鸭子,卖出t/2+1=4只;

    C.以此类推。分别可求得第一至第六个村庄的鸭子以及卖出鸭子数;

    D.利用递归函数进行递归操作,可倒叙输出经过每个村庄时所有鸭子以及卖出鸭子数量。

2.角古定理

    A.i记录计算次数;

B.首先判断输入数字是否为1:若是,则输出,若不是,进行判断;

    C.进一步判断输入数字的奇偶性:偶数,除以2,i+1;奇数,乘3+1,i+1;

    D.直到数字为1,输出i,结束。

4.算法设计

4.1卖鸭子

    A.getAnswer()函数用来倒序输出结果;

    B.在getAnswer()函数内实现递归循环;

    C.直到depth-1=0时,跳出函数,结束递归。

4.1.1算法实现

int getAnswer(int n, int depth, int cdepth){

    if (depth == 0){

        printf ("经过第%d个村庄时,共%d只, 卖出%d只\n", cdepth-depth+1, n, 0);

        return n;

    }

    else {

        int t = 2*(getAnswer(n, depth-1, cdepth)+1);

        printf ("经过第%d个村庄时,共%d只, 卖出%d只\n", cdepth-depth+1, t, t/2+1);

        return t;

    }}

4.2 角古定理

         A.fc(int n)函数用来实现递归;

         B.fc(int n)函数中共有三层判断结构;

         C.if(n == 1)判断是否为1;else if(n%2 == 0)判断是否为偶数;else后进行奇数操作。

4.2.1算法实现

int fc(int n){

    if(n == 1){

        printf("%d",n);

        return i;}

    else if(n%2 == 0){

        printf("%d\t",n);

        fc(n/2);

        i++;}

    else{

        printf("%d\t",n);

        fc(n*3+1);

        i++;}

 

 

 

 

### 关于递归和分治算法的练习题目 #### LeetCode上的递归与分治题目实例 在LeetCode平台上存在多个适合用于练习递归与分治算法思维的经典问题。例如`restore-ip-addresses`是一个典型的字符串分割类问题,它要求将给定的一串数字字符合理地划分为四个部分作为合法IP地址[^2]。 对于数值计算方面,则有`sqrtn`以及`powx-n`这样的幂运算实现题型。这些题目不仅考察了基本数学概念的理解程度,同时也测试了解决方案设计者能否巧妙运用递归来简化复杂度较高的操作流程。 #### 大整数乘法实践案例 另一个值得尝试的大整数相乘问题是理解如何通过分解大规模输入来降低单步处理难度的有效途径之一。此方法利用了分而治之的原则,在每次迭代过程中都将原始任务拆分成若干个小规模子任务直至可以直接求解为止[^3]。 #### 阶乘与斐波那契序列挑战 除了上述提到的具体应用场景外,还有两个非常经典的入门级例子——即求解n!(阶乘)及Fibonacci数列成员值。前者展示了函数自我调用机制下的累加效果;后者则体现了记忆化技术的重要性以避免重复劳动所带来的效率损失[^4]。 ```java public static BigInteger factorial(int n){ if (n <= 1) return BigInteger.ONE; else return BigInteger.valueOf(n).multiply(factorial(n - 1)); } ``` ```java public static long fibonacci(long num) { if(num<=1)return num; else return fibonacci(num-1)+fibonacci(num-2); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值