c 递归函数浅析
所谓递归,简而言之就是应用程序自身调用自身,以实现层次数据结构的查询和访问。 递归的使用可以使代码更简洁清晰,可读性更好(对于初学者到不见得),但由于递归需要系统堆栈,所以空间消耗要比非递归代码要大很多,而且,如果递归深度太大,可能系统资源会不够用。
递归分为直接递归和间接递归:简而言之,在函数中直接调用函数本身,称为直接递归调用。在函数中调用其它函数,其它函数又调用原函数,这就构成了函数自身的间接调用称为间接递归调用。
利用递归算法解题,首先要对问题的以下三个方面进行分析: 一、决定问题规模的参数。需要用递归算法解决的问题,其规模通常都是比较大的,在问题中决定规模大小(或问题复杂程度)的量有哪些?把它们找出来。二、问题的边界条件及边界值。在什么情况下可以直接得出问题的解?这就是问题的边界条件及边界值。三、解决问题的通式。把规模大的、较难解决的问题变成规模较小、易解决的同一问题,需要通过哪些步骤或等式来实现?这是解决递归问题的难点。
简单地说,函数下一次的参数是函数自身上一次的输出值,也就是说,函数的下一次执行取决于上一次的结果,即自身依赖。如求阶乘算法:
#include <stdio.h> float fun(float n)
{
if (n<)
{
exit(-);
}
else if (n==||n==) //退出条件
{
return ;
}
else
return n*fun(n-); //递归调用 } void main(void)
{
int n;
printf("请输入数(n!):\n");
scanf("%d",&n);
printf("%.f",fun(n)); //不显示小数部分的输出
return;
}
我们从递归函数fun中,可以得到:1)必须有退出条件(if);2)每次调用参数不同,但有一定的规律民(n-1);3)自身的输出作为自身的输入return。
#include <stdio.h>
#include <string.h>
void fun(char *s, int n, int b)
{
char bit[]={"0123456789ABCDEF"};
int len;
if(n==)
{
strcpy(s,"");
return;
}
fun(s, n/b, b);
len = strlen(s);
s[len] = bit[n%b];
s[len+] = '\0';
} void main(void)
{
char s[];
int i, base,old;
printf("请输入十进制数:");
scanf("%d",&old);
printf("请输入转换的进制:");
scanf("%d", &base);
fun(s, old, base);
printf("%s\n", s); return;
}
我们从递归函数fun中,可以得到:1)必须有退出条件,函数;2)每次调用参数不同,但有一定的规律民(n/b);3)逆向结果处理。
经典例子:
1 求全排列
#include<stdio.h>
#define SWAP(a,b,t) ((t)=(a),(a)=(b),(b)=(t)) //求全排列,list存放着要排列的的数据,i控制着排列的结束,
//如果第一次调用,一般为0,n是list中数据的大小,或长度。
void perm(char *list,int i,int n)
{
int j;
int temp;
if(i == n) //一个全排列已经完成,打印整个排列
{
for(j = ; j <=n; j++)
{
printf("%c",list[j]);
}
printf("\n");
}
else
{
for(j = i; j <= n; j++)
{
SWAP(list[i],list[j],temp); //依次将1,2,...n个元素放在第一个位置
perm(list,i+,n); //递归进行全排列
SWAP(list[i],list[j],temp); //由于第一个SWAP将第j个元素放到第一个位置进行了
//递归全排列,这里就将列表还原,以进行第2次递归
}
}
} int main()
{
char list[] = {'a','b','c'};
perm(list,,);
return ;
}
2斐波那契数列
又称黄金分割数列,指的是这样一个数列:1、1、2、3、5、8、13、21、……这个数列从第三项开始,每一项都等于前两项之和。又因数学家列昂纳多·斐波那契以兔子繁殖为例子而引入,故又称为“兔子数列”。一般而言,兔子在出生两个月后,就有繁殖能力,一对兔子每个月能生出一对小兔子来。如果所有兔子都不死,那么一年以后可以繁殖多少对兔子?
#include<stdio.h>
int fun(int n)
{
if(n==||n==)
{
return ;
}
else
return fun(n-)+fun(n-);
} int main()
{
int n;
printf("please input month number\n");
scanf("%d",&n);
printf("%d\n",fun(n)); return ;
}
3 汉诺塔
4求一组整数中的最大(小)值(整数是一个int[]数组,个数未知)。
参考资料
c 递归函数浅析的更多相关文章
- ACE_Message_Block实现浅析
ACE_Message_Block实现浅析1. 概述ACE_Message_Block是ACE中很重要的一个类,和ACE框架中的重要模式的实现 如ACE_Reactor, ACE_Proactor, ...
- SQL Server on Linux 理由浅析
SQL Server on Linux 理由浅析 今天的爆炸性新闻<SQL Server on Linux>基本上在各大科技媒体上刷屏了 大家看到这个新闻都觉得非常震精,而美股,今天微软开 ...
- 【深入浅出jQuery】源码浅析--整体架构
最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...
- 高性能IO模型浅析
高性能IO模型浅析 服务器端编程经常需要构造高性能的IO模型,常见的IO模型有四种: (1)同步阻塞IO(Blocking IO):即传统的IO模型. (2)同步非阻塞IO(Non-blocking ...
- netty5 HTTP协议栈浅析与实践
一.说在前面的话 前段时间,工作上需要做一个针对视频质量的统计分析系统,各端(PC端.移动端和 WEB端)将视频质量数据放在一个 HTTP 请求中上报到服务器,服务器对数据进行解析.分拣后从不同的 ...
- Jvm 内存浅析 及 GC个人学习总结
从诞生至今,20多年过去,Java至今仍是使用最为广泛的语言.这仰赖于Java提供的各种技术和特性,让开发人员能优雅的编写高效的程序.今天我们就来说说Java的一项基本但非常重要的技术内存管理 了解C ...
- 从源码浅析MVC的MvcRouteHandler、MvcHandler和MvcHttpHandler
熟悉WebForm开发的朋友一定都知道,Page类必须实现一个接口,就是IHttpHandler.HttpHandler是一个HTTP请求的真正处理中心,在HttpHandler容器中,ASP.NET ...
- 【深入浅出jQuery】源码浅析2--奇技淫巧
最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...
- javascript中的递归函数
正常的递归函数如下: function factorial(num){ ){ ; }else{ ); } } 这个函数表面看起来还ok,但如果我们执行下面代码就会出错. var jenny = fac ...
随机推荐
- linux【报错】userdel: user xiaoming is currently used by process 4713解决
学习linux的初学者肯定会遇到一些莫名其妙的问题,比如我,在学习删除一个用户的时候,就遇到上面的报错 userdel: user xiaoming is currently used by proc ...
- SQL把做个字段组合成一个字符串
- Mac OS恢复出厂系统方法
1.重新启动时按住“Command()”和"R"键盘 2.选择磁盘工具
- Windows Azure 微软公有云体验(三) IIS中文编码解决方案
Windows Azure 微软公有云已经登陆中国有一段时间了,现在是处于试用阶段,Windows Azure的使用将会给管理信息系统的开发.运行.维护带来什么样的新体验呢? Windows Azur ...
- oracle11g asm standalone 单实例重建
原文地址:oracle11g asm单实例重建has 作者:datapeng 最近到客户那里处理故障,客户说,他们修改了一下hostname,导到has出现了问题,当然,他们的数据库也就无法再启动,把 ...
- [改善Java代码] 避免instanceof非预期结果
建议18: 避免instanceof非预期结果 instanceof是一个简单的二元操作符,它是用来判断一个对象是否是一个类实例的,其操作类似于>=.==,非常简单,我们来看段程序,代码如下: ...
- 转:linux的源码查看, c++语法 查看网站
http://linux.die.net/ http://www.cplusplus.com/
- nodejs3-事件zepto.js事件
Event代表事件名,listener代表事件处理函数,括号内的参数代表可选参数: addListener(event,listener):对指定事件绑定事件处理函数 on(同上):addListen ...
- Unity3d-UI插件EZGUI官方视频教程
Showcase Teaser (D/L) – Showcases some of the things that can be accomplished using EZ GUI.#1 – Butt ...
- 小生经验贴 --- adapter的数据更新
如果你的UI是GridView ListView等需要用到adapter添加数据的控件 那么有时候里面的数据改变了 List<>内容改变了 那就要更新数据 关于adapter的数据更新 a ...