当前位置:网站首页>C语言中的 递归问题 以及将递归改写成非递归。(解析常见的几个递归题目及代码) 求阶乘、求斐波那契、汉诺塔、
C语言中的 递归问题 以及将递归改写成非递归。(解析常见的几个递归题目及代码) 求阶乘、求斐波那契、汉诺塔、
2022-08-09 13:23:00 【东区东区!】
目录
什么是递归?
程序调用自身的编程技巧称为递归( recursion)。 递归做为一种算法在程序设计语言中广泛应 用。 一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复 杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可 描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。 递归的主要思考方式在 于:把大事化小
递归的两个必要条件
1.存在限制条件,当满足这个限制条件的时候,递归便不再继续。
2.每次递归调用之后越来越接近这个限制条件。
一、接受一个整型值(无符号),按照顺序打印它的每一位。
例如: 输入:1234,输出 1 2 3 4
#include<stdio.h>
int fun(int n)
{
if(n > 9)
{
fun(n / 10);
}
printf("%d", n % 10);
return 0;
}
int main()
{
int num = 1234;
print(num);
return 0;
}二、递归求n的阶乘。
#include<stdio.h>
int fun(int n)
{
if(1 == n)
{
return 1;
}
else
{
return n * fun(n -1);
}
}
int main()
{
int n, ret;
scanf("%d", &n);
ret = fun(n);
printf("%d", ret);
return 0;
}三、递归求斐波那契数
斐波那契数列1,1,2,3,5,8…,和卢卡斯数列1,3,4,7,11,18…,具有相同的性质:从第三项开始,每一项都等于前两项之和,我们称之为斐波那契—卢卡斯递推。凡符合斐波那契—卢卡斯递推的数列就称为斐波那契—卢卡斯数列。
求第n个斐波那契数。(不考虑溢出)
#include<stdio.h>
int fun(int n)
{
if(1 == n || 2 == n)
{
return 1;
}
else
{
return fun(n -1) + fun (n - 2);
}
}
int main()
{
int n, ret;
scanf("%d", &n);
ret = fun(n);
printf("%d", ret);
return 0;
}四、汉诺塔问题
相传在古印度圣庙中,有一种被称为汉诺塔(Hanoi)的游戏。该游戏是在一块铜板装置上,有三根杆(编号A、B、C),在A杆自下而上、由大到小按顺序放置64个金盘(如图1)。游戏的目标:把A杆上的金盘全部移到C杆上,并仍保持原有顺序叠好。操作规则:每次只能移动一个盘子,并且在移动过程中三根杆上都始终保持大盘在下,小盘在上,操作过程中盘子可以置于A、B、C任一杆上。
#include<stdio.h>
int hannuota(int n, char Scr, char Dst, char Tmp) //这个函数的意思是,由A座经过B座到达C座
{
if (1 == n) //n代表由n层塔
{
printf("%c -> %c\n", Scr, Dst); //如果只有一层,直接从A挪到C,完成任务
}
else
{
hannuota(n - 1, Scr, Tmp, Dst); //超过一层,那么问题可以看作是把他n-1层,从A挪到B
printf("%c -> %c\n", Scr, Dst); //再把剩下那一层,从A挪到C;
hannuota(n - 1, Tmp, Dst, Scr); //再把那n-1层从B挪到C,完成任务
} //任务不断由n-1简化
return 0;
}
int main()
{
int n;
char TA = 'A'; //ABC分别代表三个台子
char TB = 'B';
char TC = 'C';
scanf("%d", &n);
hannuota(n, 'A', 'B', 'C');
return 0;
}运行程序,输入3,代表我们要挪动三层汉诺塔,我们得到三层汉诺塔的挪动顺序。
五、将递归改写成非递归。
通过练习上面两个问题我们发现:
在使用 fun 这个函数的时候如果我们要计算第50个斐波那契数字的时候特别耗费时间。
使用fun 函数求10000的阶乘(不考虑结果的正确性),程序会崩溃。
为什么?
在调试 fun函数的时候,如果你的参数比较大,那就会报错: `stack overflow(栈溢 出) 这样的信息。 系统分配给程序的栈空间是有限的,但是如果出现了死循环,或者(死递 归),这样有可能导致一直开辟栈空间,最终产生栈空间耗尽的情况,这样的现象我们称为栈溢 出。
如果出现这样的问题,我们可以. 使用static对象替代nonstatic局部对象。
在递归函数设计中,可以使用static对象替代nonstatic局 部对象(即栈对 象),这不仅可以减少每次递归调用和返回时产生和释放nonstatic对象的开销, 而且static对象还可以保存递归调用的中间状态,并且可为各个调用层所访问。
边栏推荐
猜你喜欢
随机推荐
音视频录入的pts和dts问题
目标检测类间不平衡问题
group by的工作原理和优化思路
Badge of openharmony container components
Spark GC日志分析
Firewalld防火墙基础
浅谈CQRS模式
如何用vs新建Asp.net项目(Web页面)
Row of openharmony container components
flink并行度知识点
openharmony容器组件之Flex
企业公众号开通微信支付
ttemp
tkiner-canvas显示图片
Es7.x使用RestHighLevelClient进行增删改和批量操作
【面试高频题】可逐步优化的链表高频题
openharmony容器组件之Counter
RTP打包发送H.264
Es7.x使用RestHighLevelClient进行查询操作
记一次 ERROR scheduler.AsyncEventQueue: Dropping event from queue shared导致OOM










