当前位置:首页 » 编程语言 » c语言递归
扩展阅读
webinf下怎么引入js 2023-08-31 21:54:13
堡垒机怎么打开web 2023-08-31 21:54:11

c语言递归

发布时间: 2022-01-24 19:58:39

c语言递归算法

用递归法计算n!
用递归法计算n!可用下述公式表示:
n!=1 (n=0,1)
n×(n-1)! (n>1)
按公式可编程如下:
long ff(int n)
{
long f;
if(n<0) printf("n<0,input error");
else if(n==0||n==1) f=1;
else f=ff(n-1)*n;
return(f);
}
main()
{
int n;
long y;
printf("\ninput a inteager number:\n");
scanf("%d",&n);
y=ff(n);
printf("%d!=%ld",n,y);
}

程序中给出的函数ff是一个递归函数。主函数调用ff 后即进入函数ff执行,如果n<0,n==0或n=1时都将结束函数的执行,否则就递归调用ff函数自身。由于每次递归调用的实参为n-1,即把n-1的值赋予形参n,最后当n-1的值为1时再作递归调用,形参n的值也为1,将使递归终止。然后可逐层退回。
下面我们再举例说明该过程。设执行本程序时输入为5,即求5!。在主函数中的调用语句即为y=ff(5),进入ff函数后,由于n=5,不等于0或1,故应执行f=ff(n-1)*n,即f=ff(5-1)*5。该语句对ff作递归调用即ff(4)。
进行四次递归调用后,ff函数形参取得的值变为1,故不再继续递归调用而开始逐层返回主调函数。ff(1)的函数返回值为1,ff(2)的返回值为1*2=2,ff(3)的返回值为2*3=6,ff(4)的返回值为6*4=24,最后返回值ff(5)为24*5=120。

Ⅱ C语言递归是什么意思

程序调用自身的编程技巧称为递归( recursion)。递归做为一种算法在程序设计语言中广泛应用。 一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解。

递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合。

一般来说,递归需要有边界条件、递归前进段和递归返回段。当边界条件不满足时,递归前进;当边界条件满足时,递归返回。



(2)c语言递归扩展阅读:

递归的应用

1、数据的定义是按递归定义的。(Fibonacci函数)

2、问题解法按递归算法实现。这类问题虽则本身没有明显的递归结构,但用递归求解比迭代求解更简单,如Hanoi问题。

3、数据的结构形式是按递归定义的。

递归的缺点

递归算法解题相对常用的算法如普通循环等,运行效率较低。因此,应该尽量避免使用递归,除非没有更好的算法或者某种特定情况,递归更为适合的时候。在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储。递归次数过多容易造成栈溢出等。


Ⅲ C语言什么是递归方法

编程里面估计最让人摸不着头脑的基本算法就是递归了。很多时候我们看明白一个复杂的递归都有点费时间,尤其对模型所描述的问题概念不清的时候,想要自己设计一个递归那么就更是有难度了。今天我也花费了半个小时来搞明白二叉树的平衡性的递归模型,首先我不明白什么叫做平衡性,所以花费的时候大部分实在试探理解平衡性的含义。在搞明白的时候,我突然想到假如让我来设计,在我知道平衡性的前提下,我是否可以建立如此简洁的递归模型。为此,我遇到的问题是我们到底在什么情况下适用递归模型,并且递归模型如何建立。


数学都不差的我们,第一反应就是递归在数学上的模型是什么。毕竟我们对于问题进行数学建模比起代码建模拿手多了。 (当然如果对于问题很清楚的人也可以直接简历递归模型了,运用数模做中介的是针对对于那些问题还不是很清楚的人)


自己观察递归,我们会发现,递归的数学模型其实就是归纳法,这个在高中的数列里面是最常用的了。回忆一下归纳法。


归纳法适用于想解决一个问题转化为解决他的子问题,而他的子问题又变成子问题的子问题,而且我们发现这些问题其实都是一个模型,也就是说存在相同的逻辑归纳处理项。当然有一个是例外的,也就是递归结束的哪一个处理方法不适用于我们的归纳处理项,当然也不能适用,否则我们就无穷递归了。这里又引出了一个归纳终结点以及直接求解的表达式。如果运用列表来形容归纳法就是:


步进表达式:问题蜕变成子问题的表达式

结束条件:什么时候可以不再是用步进表达式

直接求解表达式:在结束条件下能够直接计算返回值的表达式

逻辑归纳项:适用于一切非适用于结束条件的子问题的处理,当然上面的步进表达式其实就是包含在这里面了。


这样其实就结束了,递归也就出来了。

递归算法的一般形式:

voidfunc(mode)
{
if(endCondition)
{
constExpression//基本项
}
else
{
accumrateExpreesion/归纳项
mode=expression//步进表达式
func(mode)//调用本身,递归
}
}

最典型的就是N!算法,这个最具有说服力。理解了递归的思想以及使用场景,基本就能自己设计了,当然要想和其他算法结合起来使用,还需要不断实践与总结了。

例如:返回一个二叉树的深度:

intdepth(Treet){
if(!t)return0;
else{
inta=depth(t.right);
intb=depth(t.left);
return(a>b)?(a+1):(b+1);
}
}


判断一个二叉树是否平衡:

intisB(Treet){
if(!t)return0;
intleft=isB(t.left);
intright=isB(t.right);
if(left>=0&&right>=0&&left-right<=1||left-right>=-1)
return(left<right)?(right+1):(left+1);
elsereturn-1;
}


上面这两个递归的难易程度就不一样了,第一个关于深度的递归估计只要了解递归思想的都可以短时间设计出来,但第二个估计就要长点时间了。纯递归问题的难易主要纠结于一些条件表达式的构造以及初值的设置(上面的为直接表达式值的设定)。

最后需要补充的是,很多不理解递归的人,总认为递归完全没必要,用循环就可以实现,其实这是一种很肤浅的理解。因为递归之所以在程序中能风靡并不是因为他的循环,大家都知道递归分两步,递和归,那么可以知道递归对于空间性能来说,简直就是造孽,这对于追求时空完美的人来说,简直无法接接受,如果递归仅仅是循环,估计现在我们就看不到递归了。递归之所以现在还存在是因为递归可以产生无限循环体,也就是说有可能产生100层也可能10000层for循环。例如对于一个字符串进行全排列,字符串长度不定,那么如果你用循环来实现,你会发现你根本写不出来,这个时候就要调用递归,而且在递归模型里面还可以使用分支递归,例如for循环与递归嵌套,或者这节枚举几个递归步进表达式,每一个形成一个递归。

Ⅳ C语言递归函数

P(X=k)=[n!/(k!(n-k)!]*p^k*(1-p)^(n-k)
=[(n-k+1)/k]*[p/(1-p)]*[n!/(k-1)!(n-k+1)!]*p^(k-1)*(1-p)^(n-k+1)
=[(n-k+1)/k]*[p/(1-p)]*P(X=k-1),

[(n-k+1)/k]*[p/(1-p)]>1时,即k<(n+1)p时,P(X=k)>P(X=k-1),k值较小时,P(X=k)随k的增大而增大,
[(n-k+1)/k]*[p/(1-p)]<1时,即k>(n+1)p时,P(X=k)<P(X=k-1),k值较大时,P(X=k)随k的增大而减小,
[(n-k+1)/k]*[p/(1-p)]=1时,即k=(n+1)p时,P(X=k)=P(X=k-1).(n+1)p为正整数时,有两个最大值。

Ⅳ c语言递归函数

递归(recursion)就是子程序(或函数)直接调用自己或通过一系列调用语句间接调用自己,是一种描述问题和解决问题的基本方法。
递归通常用来解决结构自相似的问题。所谓结构自相似,是指构成原问题的子问题与原问题在结构上相似,可以用类似的方法解决。具体地,整个问题的解决,可以分为两部分:第一部分是一些特殊情况,有直接的解法;第二部分与原问题相似,但比原问题的规模小。实际上,递归是把一个不能或不好解决的大问题转化为一个或几个小问题,再把这些小问题进一步分解成更小的问题,直至每个小问题都可以直接解决。因此,递归有两个基本要素:
(1)边界条件:确定递归到何时终止,也称为递归出口。
(2)递归模式:大问题是如何分解为小问题的,也称为递归体。递归函数只有具备了这两个要素,才能在有限次计算后得出结果
汉诺塔问题:对汉诺塔问题的求解,可以通过以下3个步骤实现:
(1)将塔上的n-1个碟子借助塔C先移到塔B上;
(2)把塔A上剩下的一个碟子移到塔C上;
(3)将n-1个碟子从塔B借助塔A移到塔C上。
在递归函数中,调用函数和被调用函数是同一个函数,需要注意的是递归函数的调用层次,如果把调用递归函数的主函数称为第0层,进入函数后,首次递归调用自身称为第1层调用;从第i层递归调用自身称为第i+1层。反之,退出第i+1层调用应该返回第i层。采用图示方法描述递归函数的运行轨迹,从中可较直观地了解到各调用层次及其执行情况,具体方法如下:
(1)写出函数当前调用层执行的各语句,并用有向弧表示语句的执行次序;
(2)对函数的每个递归调用,写出对应的函数调用,从调用处画一条有向弧指向被调用函数入口,表示调用路线,从被调用函数末尾处画一条有向弧指向调用语句的下面,表示返回路线;
(3)在返回路线上标出本层调用所得的函数值。n=3时汉诺塔算法的运行轨迹如下图所示,有向弧上的数字表示递归调用和返回的执行顺序
三、递归函数的内部执行过程
一个递归函数的调用过程类似于多个函数的嵌套的调用,只不过调用函数和被调用函数是同一个函数。为了保证递归函数的正确执行,系统需设立一个工作栈。具体地说,递归调用的内部执行过程如下:
(1)运动开始时,首先为递归调用建立一个工作栈,其结构包括值参、局部变量和返回地址;
(2)每次执行递归调用之前,把递归函数的值参和局部变量的当前值以及调用后的返回地址压栈;
(3)每次递归调用结束后,将栈顶元素出栈,使相应的值参和局部变量恢复为调用前的值,然后转向返回地址指定的位置继续执行。
上述汉诺塔算法执行过程中,工作栈的变化如下图所示,其中栈元素的结构为(返回地址,n值,A值,B值,C值),返回地址对应算法中语句的行号,分图的序号对应图中递归调用和返回的序号
我可以帮助你,你先设置我最佳答案后,我网络Hii教你。

Ⅵ c语言递归!!

上面递归调用中每次调用后n的值都是一样的,都为4,因为n1的值没变;按题目正确的应该是:
main()
{int n=1;
for(int m=1;m<=4;m++)
n=(n+1)*2;
printf("%d",n);
}
而且你的语法也有错误,printf("%d",n) 后面少了分号……

Ⅶ C语言(递归)

感觉到你的程序中:①数据类型尚未理顺,②算阶乘倒数的递归算法尚待完美。下面是按此两点改进的程序:
#include
<stdio.h>
long
f(long
n)
{

if(n
==
0
||
n
==
1)

return
1;

else

return
n*f(n-1);
}
void
main()
{

double
s
=
0.0;

int
i,n;

printf("input
ainteger
number
n:");

scanf("%d",&n);

for(i
=
1;
i
<=n;
i++)

s+=
1.0/f(i);

printf("%lf",s);

return
0;
}
程序的四种运行结果如下:

Ⅷ 在C语言中什么叫递归

递归:就是自己调自己,但是没终止条件会死循环,所以你的递归代码里有结束自调自的条件,这样就创造了有限次的循环(代码中你看不到for或foreach但是有循环发生)

Ⅸ C语言递归

你这怕是理解错了,编程语言共通的,我用java给你写个示例

importjava.util.ArrayList;
importjava.util.List;

publicclassTest1{
publicstaticvoidmain(String[]args)throwsException{
inta=test(5,8);
System.out.println(a);
}

privatestaticinttest(inti,inti1){
if(i==0){
return0;
}
if(i1==0){
return1;
}
if(i1==1){
returni;
}
else{
returni*test(i,i1-1);
}
}
}

运行结果

390625

Processfinishedwithexitcode0

Ⅹ 讲一下c语言中递归函数的使用方法

相当于循环,要有判断条件,传递进去的参数要变化,满足条件调用自身,不满足条件就开始一层一层返回。简单例子:
int
f(int
i){
int
sum=0;
if(i>0)
sum+=f(i-1);
return
sum;
}
main(){
int
a=10;
printf("%d",f(a));
}