高羊茅混播播种最适合温度是多少? 当前位置:首页>高羊茅混播播种最适合温度是多少?>正文

高羊茅混播播种最适合温度是多少?

发布时间:2019-04-23

原标题:斐波那契与尾递归

尾递归wiki解释如下:

  • 尾部递归是一种编程技巧。递归函数是指一些会在函数内调用自己的函数,如果在递归函数中,递归调用返回的结果总被直接返回,则称为尾部递归。尾部递归的函数有助将算法转化成函数编程语言,而且从编译器角度来说,亦容易优化成为普通循环。这是因为从电脑的基本面来说,所有的循环都是利用重复移跳到代码的开头来实现的。如果有尾部归递,就只需要叠套一个堆栈,因为电脑只需要将函数的参数改变再重新调用一次。利用尾部递归最主要的目的是要优化,例如在Scheme语言中,明确规定必须针对尾部递归作优化。可见尾部递归的作用,是非常依赖于具体实现的。

  • 我们还是从简单的斐波那契开始了解尾递归吧。

  • 用普通的递归计算Fibonacci数列:

#include "stdio.h"
#include "math.h"

int factorial(int n);

int main(void)
{
    int i, n, rs;

    printf("请输入斐波那契数n:");
    scanf("%d",&n);

    rs = factorial(n);
    printf("%d 
", rs);

    return 0;
}

// 递归
int factorial(int n)
{
    if(n <= 2)
    {
        return 1;
    }
    else
    {
        return factorial(n-1) + factorial(n-2);
    }
}

程序员运行结果如下:

请输入斐波那契数n:20
6765

Process returned 0 (0x0) execution time : 3.502 s
Press any key to continue.
在i5的CPU下也要花费 3.502 秒的时间。

下面我们看看如何用尾递归实现斐波那契数。

/#include "stdio.h"
/#include "math.h"

int factorial(int n);

int main(void)
{
    int i, n, rs;

    printf("请输入斐波那契数n:");
    scanf("%d",&n);

    rs = factorial_tail(n, 1, 1);
    printf("%d ", rs);

    return 0;
}

int factorial_tail(int n,int acc1,int acc2)
{
    if (n < 2)
    {
        return acc1;
    }
    else
    {
        return factorial_tail(n-1,acc2,acc1+acc2);
    }
}
  • 程序员运行结果如下:

请输入斐波那契数n:20
6765
Process returned 0 (0x0) execution time : 1.460 s
Press any key to continue.
快了一倍有多。当然这是不完全统计,有兴趣的话可以自行计算大规模的值,这里只是介绍尾递归而已。

我们可以打印一下程序的执行过程,函数加入下面的打印语句:

int factorial_tail(int n,int acc1,int acc2)
{
    if (n < 2)
    {
        return acc1;
    }
    else
    {
        printf("factorial_tail(%d, %d, %d) 
",n-1,acc2,acc1+acc2);
        return factorial_tail(n-1,acc2,acc1+acc2);
    }
}

程序运行结果:

请输入斐波那契数n:10
factorial_tail(9, 1, 2)
factorial_tail(8, 2, 3)
factorial_tail(7, 3, 5)
factorial_tail(6, 5, 8)
factorial_tail(5, 8, 13)
factorial_tail(4, 13, 21)
factorial_tail(3, 21, 34)
factorial_tail(2, 34, 55)
factorial_tail(1, 55, 89)
55
Process returned 0 (0x0)   execution time : 1.393 s
Press any key to continue.
从上面的调试就可以很清晰地看出尾递归的计算过程了。acc1就是第n个数,而acc2就是第n与第n+1个数的和,这就是我们前面讲到的“迭代”的精髓,计算结果参与到下一次的计算,从而减少很多重复计算量。

fibonacci(n-1,acc2,acc1+acc2)真是神来之笔,原本朴素的递归产生的栈的层次像二叉树一样,以指数级增长,但是现在栈的层次却像是数组,变成线性增长了,实在是奇妙,总结起来也很简单,原本栈是先扩展开,然后边收拢边计算结果,现在却变成在调用自身的同时通过参数来计算。

当前文章:http://nsmsa.com.cn/367ta.html

发布时间:2019-04-23 15:27:01

【视频】高度30公分40公分50公分大叶黄杨苗_苗圃现场 哪些地方适合长紫藤? 紫藤花可以盆栽吗? 贵州的八宝景天都在哪里买的? 苗圃直销金边黄杨苗 掉队了吧,桃树的果子是五果之首你知道吗 【保养秘笈】凌霄花是用了什么保养品,不然怎会有如此之容貌呢? 专家预测2016下半年食用玫瑰苗价格行情走势 绣球花怕冻吗? 北方草坪品种哪个好

33339 49113 29569 88147 66645 73949 61134 73877 86160 47188 12993 26045 12323 76298 69309 42993 48361 21923 12479 30177 41565 25706 55174

责任编辑:成平卓纯