精华内容
下载资源
问答
  • C语言递归算法

    2020-04-14 11:28:41
    递归算法的核心就是对自身的不断调用,但是必须要有递归出口 1、计算阶乘 int factorial(int n){ if(n == 1) return 1;//这里就是的递归的出口 else return n * factorial(n - 1); } 2、汉罗塔问题 void Hanoi...

    递归算法的核心就是对自身的不断调用,但是必须要有递归出口
    1、计算阶乘

    int factorial(int n){
        if(n == 1)
            return 1;//这里就是的递归的出口
        else
          return n * factorial(n - 1);
    }
    
    

    2、汉罗塔问题

    void Hanoi (int n, char A, char B, char C){
        if (n==1){ //end condition
            move(A,B);//‘move’ can be defined to be a print function递归出口
        }
        else{
            Hanoi(n-1,A,C,B);//move sub [n-1] pans from A to B
            move(A,C);//move the bottom(max) pan to C
            Hanoi(n-1,B,A,C);//move sub [n-1] pans from B to C
            //当三个或两个递归在一块的时候,按顺序执行,之后递归
        }
    }
    
    展开全文
  • c语言实现递归算法求N的阶乘

    千次阅读 2018-09-26 17:26:53
    #include #include int factorial(int n) { if (n == 0) { return 1; } else return n * factorial(n - 1); }; int main() ... printf("%d的阶乘结果为:%d \n", n, factorial(n)); }  
    #include<stdio.h>
    #include<math.h>
    
    int factorial(int n)
    {
    	if (n == 0)
    	{
    		return 1;
    	}
    	else
    		return n * factorial(n - 1);
    };
    
    int main()
    {
    	int n;
    	printf("请输入您要求的阶乘数:");
    	scanf("%d/n", &n);
    	printf("%d的阶乘结果为:%d \n", n, factorial(n));
    }

     

    展开全文
  • 许多教科书都把计算机阶乘和菲波那契数列用来说明递归,非常不幸我们可爱的著名的老潭老师的《C语言程序设计》一书中就是从阶乘的计算开始的函数递归。导致读过这本经书的同学们,看到阶乘计算第一个想法就是递归。...
  • 许多教科书都把计算机阶乘和菲波那契数列用来说明递归,非常不幸我们可爱的著名的老潭老师的《C语言程序设计》一书中就是从阶乘的计算开始的函数递归。导致读过这本经书的同学们,看到阶乘计算第一个想法就是递归。...

    许多教科书都把计算机阶乘和菲波那契数列用来说明递归,非常不幸我们可爱的著名的老潭老师的《C语言程序设计》一书中就是从阶乘的计算开始的函数递归。导致读过这本经书的同学们,看到阶乘计算第一个想法就是递归。但是在阶乘的计算里,递归并没有提供任何优越之处。在菲波那契数列中,它的效率更是低的非常恐怖。

    这里有一个简单的程序,可用于说明递归。程序的目的是把一个整数从二进制形式转换为可打印的字符形式。例如:给出一个值4267,我们需要依次产生字符‘4',‘2',‘6',和‘7'。就如在printf函数中使用了%d格式码,它就会执行类似处理。

    我们采用的策略是把这个值反复除以10,并打印各个余数。例如,4267除10的余数是7,但是我们不能直接打印这个余数。我们需要打印的是机器字符集中表示数字‘7'的值。在ASCII码中,字符‘7'的值是55,所以我们需要在余数上加上48来获得正确的字符,但是,使用字符常量而不是整型常量可以提高程序的可移植性。‘0'的ASCII码是48,所以我们用余数加上‘0',所以有下面的关系:

    ‘0'+ 0 =‘0'

    ‘0'+ 1 =‘1'

    ‘0'+ 2 =‘2'

    ...

    从这些关系中,我们很容易看出在余数上加上‘0'就可以产生对应字符的代码。接着就打印出余数。下一步再取商的值,4267/10等于426。然后用这个值重复上述步骤。

    这种处理方法存在的唯一问题是它产生的数字次序正好相反,它们是逆向打印的。所以在我们的程序中使用递归来修正这个问题。

    我们这个程序中的函数是递归性质的,因为它包含了一个对自身的调用。乍一看,函数似乎永远不会终止。当函数调用时,它将调用自身,第2次调用还将调用自身,以此类推,似乎永远调用下去。这也是我们在刚接触递归时最想不明白的事情。但是,事实上并不会出现这种情况。

    这个程序的递归实现了某种类型的螺旋状while循环。while循环在循环体每次执行时必须取得某种进展,逐步迫近循环终止条件。递归函数也是如此,它在每次递归调用后必须越来越接近某种限制条件。当递归函数符合这个限制条件时,它便不在调用自身。

    在程序中,递归函数的限制条件就是变量quotient为零。在每次递归调用之前,我们都把quotient除以10,所以每递归调用一次,它的值就越来越接近零。当它最终变成零时,递归便告终止。

    /*接受一个整型值(无符号0,把它转换为字符并打印它,前导零被删除*/

    #include

    int binary_to_ascii( unsigned int value)

    {

    unsigned int quotient;

    quotient = value / 10;

    if( quotient != 0)

    binary_to_ascii( quotient);

    putchar ( value % 10 + '0' );

    }

    递归是如何帮助我们以正确的顺序打印这些字符呢?下面是这个函数的工作流程。

    1. 将参数值除以10

    2. 如果quotient的值为非零,调用binary-to-ascii打印quotient当前值的各位数字

    3. 接着,打印步骤1中除法运算的余数

    注意在第2个步骤中,我们需要打印的是quotient当前值的各位数字。我们所面临的问题和最初的问题完全相同,只是变量quotient的值变小了。我们用刚刚编写的函数(把整数转换为各个数字字符并打印出来)来解决这个问题。由于quotient的值越来越小,所以递归最终会终止。

    一旦你理解了递归,阅读递归函数最容易的方法不是纠缠于它的执行过程,而是相信递归函数会顺利完成它的任务。如果你的每个步骤正确无误,你的限制条件设置正确,并且每次调用之后更接近限制条件,递归函数总是能正确的完成任务。

    但是,为了理解递归的工作原理,你需要追踪递归调用的执行过程,所以让我们来进行这项工作。追踪一个递归函数的执行过程的关键是理解函数中所声明的变量是如何存储的。当函数被调用时,它的变量的空间是创建于运行时堆栈上的。以前调用的函数的变量扔保留在堆栈上,但他们被新函数的变量所掩盖,因此是不能被访问的。

    当递归函数调用自身时,情况于是如此。每进行一次新的调用,都将创建一批变量,他们将掩盖递归函数前一次调用所创建的变量。当我追踪一个递归函数的执行过程时,必须把分数不同次调用的变量区分开来,以避免混淆。

    程序中的函数有两个变量:参数value和局部变量quotient。下面的一些图显示了堆栈的状态,当前可以访问的变量位于栈顶。所有其他调用的变量饰以灰色的阴影,表示他们不能被当前正在执行的函数访问。

    假定我们以4267这个值调用递归函数。当函数刚开始执行时,堆栈的内容如下图所示:

    93357a72f0cc3d8a7c83351e803ab787.png

    执行除法之后,堆栈的内容如下:

    08fa9b36507c3448fd2c96d793ddf667.png

    接着,if语句判断出quotient的值非零,所以对该函数执行递归调用。当这个函数第二次被调用之初,堆栈的内容如下:

    7e144b507643dd931bce4ff1c09bd18c.png

    堆栈上创建了一批新的变量,隐藏了前面的那批变量,除非当前这次递归调用返回,否则他们是不能被访问的。再次执行除法运算之后,堆栈的内容如下:

    d5b45acc1f244ce1ae4a307f1ba73511.png

    quotient的值现在为42,仍然非零,所以需要继续执行递归调用,并再创建一批变量。在执行完这次调用的出发运算之后,堆栈的内容如下:

    7bfacc9b09d67f0ab449d8439d5b4b20.png

    此时,quotient的值还是非零,仍然需要执行递归调用。在执行除法运算之后,堆栈的内容如下:

    f9715af3249387ef4224cb9c801a6b62.png

    不算递归调用语句本身,到目前为止所执行的语句只是除法运算以及对quotient的值进行测试。由于递归调用这些语句重复执行,所以它的效果类似循环:当quotient的值非零时,把它的值作为初始值重新开始循环。但是,递归调用将会保存一些信息(这点与循环不同),也就好是保存在堆栈中的变量值。这些信息很快就会变得非常重要。

    现在quotient的值变成了零,递归函数便不再调用自身,而是开始打印输出。然后函数返回,并开始销毁堆栈上的变量值。

    每次调用putchar得到变量value的最后一个数字,方法是对value进行模10取余运算,其结果是一个0到9之间的整数。把它与字符常量‘0'相加,其结果便是对应于这个数字的ASCII字符,然后把这个字符打印出来。

    输出4:

    f9715af3249387ef4224cb9c801a6b62.png

    接着函数返回,它的变量从堆栈中销毁。接着,递归函数的前一次调用重新继续执行,她所使用的是自己的变量,他们现在位于堆栈的顶部。因为它的value值是42,所以调用putchar后打印出来的数字是2。

    输出42:

    33d288eb5f6dca43a4eadd627c3ddcba.png

    接着递归函数的这次调用也返回,它的变量也被销毁,此时位于堆栈顶部的是递归函数再前一次调用的变量。递归调用从这个位置继续执行,这次打印的数字是6。在这次调用返回之前,堆栈的内容如下:

    输出426:

    c7c6b4af08eae62eb8a875338e78b965.png

    现在我们已经展开了整个递归过程,并回到该函数最初的调用。这次调用打印出数字7,也就是它的value参数除10的余数。

    输出4267:

    a26e25e53a6dec798a2ae782312b7551.png然后,这个递归函数就彻底返回到其他函数调用它的地点。

    如果你把打印出来的字符一个接一个排在一起,出现在打印机或屏幕上,你将看到正确的值:4267

    使用递归一定要有跳出的条件:

    这是一个最简单的递归, 不过它会一直执行, 可用 Ctrl+C 终止.

    #include

    void prn(int num) {

    printf("%d/n", num);

    if (num > 0) prn(--num);

    }

    int main(void)

    {

    prn(9);

    getchar();

    return 0;

    }

    实例: 翻转字符串

    #include

    void revers(char *cs);

    int main(void)

    {

    revers("123456789");

    getchar();

    return 0;

    }

    void revers(char *cs)

    {

    if (*cs)

    {

    revers(cs + 1);

    putchar(*cs);

    }

    }

    实例: 阶乘#include

    int factorial(int num);

    int main(void)

    {

    int i;

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

    printf("%d: %d/n", i, factorial(i));

    getchar();

    return 0;

    }

    int factorial(int num)

    {

    if (num == 1)

    return(1);

    else

    return(num * factorial(num-1));

    }

    实例: 整数到二进制#include

    void IntToBinary(unsigned num);

    int main(void)

    {

    IntToBinary(255); /* 11111111 */

    getchar();

    return 0;

    }

    void IntToBinary(unsigned num) {

    int i = num % 2;

    if (num > 1) IntToBinary(num / 2);

    putchar(i ? '1' : '0');

    //    putchar('0' + i);  /* 可代替上面一句 */

    }

    剖析递归:#include

    void prn(unsigned n);

    int main(void)

    {

    prn(1);

    getchar();

    return 0;

    }

    void prn(unsigned n) {

    printf("%d: %p/n", n, &n);  /* A */

    if (n < 4)

    prn(n+1);               /* B */

    printf("%d: %p/n", n, &n);  /* C */

    }

    例输出效果图:

    1a91e7400238c5240387ff234d0c194e.png

    分析:程序运行到 A, 输出了第一行.

    此时 n=1, 满足 < 4 的条件, 继续执行 B 开始了自调用(接着会输出第二行); 注意 n=1 时语句 C 还有待执行.

    ...如此循环, 一直到 n=4, A 可以执行, 但因不满足条件 B 执行不了了; 终于在 n=4 时得以执行 C.

    但此时内存中有四个函数都等待返回(分别是 n=1、2、3、4 时), 咱们分别叫它 f1、f2、f3、f4.

    f4 执行 C 输出了第五行, 函数返回, 返回给 f3(此时 n=3), f3 得以继续执行 C, 输出了第六行.

    f3 -> f2 -> 继续 C, 输出了第七行.

    f2 -> f1 -> 继续 C, 输出了第八行, 执行完毕!

    如此看来, 递归函数还是很费内存的(有时不如直接使用循环), 但的确很巧妙.

    展开全文
  • C语言-递归算法以及经典递归(Hanoi)

    万次阅读 多人点赞 2015-08-02 19:54:28
    递归算法(recursion)计算阶乘 codes: /************************************** *author: Yang Xu *goals: compute factorial by recursion ***************************************/ #include #include int...

    用递归算法(recursion)计算阶乘

    codes:

    /**************************************
    *author: Yang Xu
    *goals: compute factorial by recursion
    ***************************************/

    #include<stdio.h>
    #include<process.h>

    int main()
    {
        /*print the result of factorial*/
        printf("%d\n", f(5));
        system("pause");
        return 0;    
    }

    int f(int n)
    {
        int x;
        /*这里就不加关于负整数的判断了*/
        if(n==1||n==0)
            x=1;
        else
            x=n*f(n-1);//the recursion
        return x;
    }


    奇怪的是,我把自定义函数加在了主函数的后面,在主函数中也没有声明,但是却运行成功了。LOL


    递归算法的精髓是一层入一层,直至遇到满足的结束语句,所以一般和递归在一起的是一些判断语句。递归函数得要有终止语句。

    遇到递归问题需要根据规律解决。

    1、找到所谓的终止条件,即让递归停止的条件

    2、找到递推的关系式

    3、递归的方向要搞清楚,一般是向最终的终止条件不断递归

    4、递归 分为回推和递推两个阶段,当递推到终止条件时,程序会反向推回(回推)!!!!

    一般会出现递归不像递归的情况,这个要小心


    例题:

    猴子第一天摘下N个桃子,当时就吃了一半,还不过瘾,就又多吃了一个。第二天又将剩下的桃子吃掉一半,又多吃了一个。以后每天都吃前一天剩下的一半零一个。到第10天在想吃的时候就剩一个桃子了,问第一天共摘下来多少个桃子?并反向打印每天所剩桃子数。


    /**************************************
    *author: Yang Xu
    *goals: compute a question of monkey eatting pitches by recursion
    ***************************************/

    #include<stdio.h>
    #include<process.h>

    int main()
    {
        /*打印最初的桃子数量*/
        printf("%d\n", f(1));
        system("pause");
        return 0;
    }

    /*第day天剩下的桃子数*/
    int f(int day)
    {
        int n;
        if(day==10)
            n=1;
        else
        {
            /*第day天(左)和第day+1天(右)所剩桃子的关系式*/
            n=(f(day+1)+1)*2;
            /*由于递归规律,直接倒序打印*/
            printf("第%d天所剩桃子%d个\n", day, n);
        }
        return n;
    }


    递归过程中伴随着参量内存的不断释放与使用,需要注意,这个是函数参量的问题,这里不多做分析


    Hanoi Tower

    展开全文
  • C语言递归算法的分析

    千次阅读 2013-06-19 10:00:22
     许多教科书都把计算机阶乘和菲波那契数列用来说明递归,非常不幸我们可爱的著名的老潭老师的《C语言程序设计》一书中就是从阶乘的计算开始的函数递归。导致读过这本经书的同学们,看到阶乘计算第一个想法就是递归...
  • //递归和非递归分别实现求n的阶乘 #include&lt;stdio.h&gt; #include&lt;stdlib.h&gt; //非递归 //int test(int x) //{ // int i = 0; // int sum = 1; // // for (i = 1; i &lt;= x; i++) /...
  • C语言递归算法练习 文章目录 C语言递归算法练习 练习代码 N的阶乘 斐波那契数 打印每位数字 strlen模拟(测量字符串长度) N的K次方 字符串逆序    递归是一种算法设计中常用的一种方法,其实就是一个过程或者函数...
  • 系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要...递归是一种很重要的算法,特别时对于初学算法人员来说! 一、递归阶乘 递归本质也是一种循环! 二、代码内容 1.代码示例 /*递归求...
  • 我们将以两个经典问题为例子,升级我们的递归成为尾递归。尾递归顾名思义就是尾处递归,其实不然。就我的理解,就是将递归函数多加了几个参数,并将结果保存在参数中,这就略去了函数回调的代价。以往我们求斐波那契...
  • 主要介绍了C语言程序中递归算法的使用实例教程,递归经常被用来进行阶乘和比较大小等计算工作,文中举的都是一些基础的例子,需要的朋友可以参考下
  • 递归算法_阶乘(C语言)

    千次阅读 2019-07-23 09:34:02
    递归算法,就是一种直接或者间接地调用自身地算法。递归算法的具体实现过程一般通过函数或者子过程来完成,在函数或子过程的内部,编写代码直接或间接地调用自己,即可完成递归操作。 求6!= 65432*1 C语言相关...
  • C语言递归的原理

    千次阅读 多人点赞 2018-05-06 22:54:06
    递归的底层实现其实是栈,而栈是先进后出的(即先入栈的反而后出栈(类似水瓶中放物取物))下面是一段阶乘递归的案例代码#include&lt;stdio.h&gt; //一个求阶乘的递归算法 int f(int n) { ...
  • C++实现的:递归实现阶乘算法N! 1、 递归实现n! 题目描述:输入n值,求解n的阶乘 方法一:累乘法 方法二:递归法 源码: 一、 递归实现n! 1、 累乘法 #include using namespace std; #define UL unsigned ...
  • C语言递归解决阶乘问题

    千次阅读 2018-07-14 07:45:15
    递归函数的概念是:直接或者间接地调用自身的算法递归函数:用函数自身给出定义的函数而且在学习的后期 学到了分治法可以感觉到分治法产生的子问题是原问题的较小模式,这就为使用递归技术提供了不小的方便即在合适...
  • 循环法还是比较简单的,就先输入你要求的阶乘n,然后一直自减 #include <stdio.h> main() { long n,sum=1;//10 以上的阶乘就比较大了 int i; printf("请输入你要求的阶乘:") scanf("%d",&n);//先输入...
  • 使用递归算法求出 5 的阶乘的值 #include<stdio.h> int factorial(int a) { int temp = a; if (a < 0) { printf("error"); } else if(a==0 || a==1) { temp = 1; return temp; } else { ...
  • 基础算法,数据结构,阶乘思想,采用c语言实现,对于数据结构基础的学习有帮助
  •  许多教科书都把计算机阶乘和菲波那契数列用来说明递归,非常不幸我们可爱的著名的老潭老师的《C语言程序设计》一书中就是从阶乘的计算开始的函数递归。导致读过这本经书的同学们,看到阶乘计算第一个想法就是递归...

空空如也

空空如也

1 2 3 4 5 ... 8
收藏数 156
精华内容 62
关键字:

c语言阶乘递归算法

c语言 订阅