【万字总结】探讨递归与迭代的区别与联系及如何求解10000的阶层

递归和迭代

这两个概念也许很多童鞋依旧分不清楚,下面通过求解斐波那契数来看看它们俩的关系吧。

斐波那契数的定义:

f0=0

f1=1

fi=fi1+fi2(i>1)

递归:

(factorial 6)
(* 6 (factorial 5))
(* 6 (* 5 (factorial 4)))
(* 6 (* 5 (* 4 (factorial 3))))
(* 6 (* 5 (* 4 (* 3 (factorial 2)))))
(* 6 (* 5 (* 4 (* 3 (2 (factorial 1))))))
(* 6 (* 5 (* 4 (* 3 (* 2 1)))))
(* 6 (* 5 (* 4* 3 2))))
(* 6 (* 5 (* 4 6)))
(* 6 (* 5 24))
(* 6 120)
720

迭代:

(factorial 6)
(factorial 1 1 6)
(factorial 1 2 6)
(factorial 2 3 6)
(factorial 6 4 6)
(factorial 24 5 6)
(factorial 120 6 6)
(factorial 720 7 6)
720

递归的核心在于:不断地回到起点
迭代的核心在于:不断地更新参数

在下面的代码中:

递归的核心是sum的运算,sum不断的累乘,虽然运算的数值不同,但形式和意义一样。

而迭代的核心是product和counter的不断更新。如上表中,product就是factorial的前2个参数不断的累乘更新成第一个参数;而第二个参数则是counter,其不断的加1来更新自己。

product <- counter * product 
counter < - counter + 1
#include <iostream>

using namespace std;

int factorialRecursive(int n);
int factorialIteration(int product, int counter, int max_count);

int main()
{
    int n;
    cout<<"Enter an integer:"<<endl;
    cin>>n;
    cout<<factorialRecursive(n)<<endl;
    cout<<factorialIteration(1,1,n)<<endl;

    return 0;
}

int factorialRecursive(int n)
{
    int sum=1;
    if(n==1)
        sum*=1;
    else
        sum=n*factorialRecursive(n-1);
    return sum;
}

int factorialIteration(int product, int counter, int max_count)
{
    int sum=1;
    if(counter>max_count)
        sum*=product;
    else
        factorialIteration((counter*product),(counter+1),max_count);
}

补充问题:

关于上面的factorialIteration函数,今天收到一份邮件,我也通过再次分析学到了很多,这里罗列一下。


第一个问题:

首先来看相对简单的问题,该童鞋在函数内以两种不同方式加上another_sum=2却有着不同的结果。

int factorialIteration(int product, int counter, int max_count)
{
    int sum=1;
    int another_sum=2;
    if(counter>max_count)
    {
        sum*=product;
        another_sum*=product;
    }    
    else
        factorialIteration((counter*product),(counter+1),max_count);
}
int factorialIteration(int product, int counter, int max_count)
{
    int sum=1;
    int another_sum=2;
    if(counter>max_count)
    {
        another_sum*=product;
        sum*=product;

    }    
    else
        factorialIteration((counter*product),(counter+1),max_count);
}

因为这个函数声明的是int型的返回类型,但没有用return语句,所以C++自动将其运行的最后一行语句作为了返回语句。所以这两个函数类似于:

int factorialIteration(int product, int counter, int max_count)
{
    int sum=1;
    int another_sum=2;
    if(counter>max_count)
    {
        sum*=product;
        return another_sum*=product;
    }
    else
        factorialIteration((counter*product),(counter+1),max_count);
}


int factorialIteration(int product, int counter, int max_count)
{
    int sum=1;
    int another_sum=2;
    if(counter>max_count)
    {
        another_sum*=product;
        return sum*=product;
    }
    else
        factorialIteration((counter*product),(counter+1),max_count);
}

然而我在CodeBlocks中写的代码不用return是可以的,但在Visual Studio中却是会报错的。

有了这个发现,我原来的代码也可以这样来写:

#include <iostream>

using namespace std;

int factorialRecursive(int n);
int factorialIteration(int product, int counter, int max_count);

int main()
{
    int n;
    cout<<"Enter an integer:"<<endl;
    cin>>n;
    cout<<factorialRecursive(n)<<endl;
    cout<<factorialIteration(1,1,n)<<endl;

    return 0;
}

int factorialRecursive(int n)
{
    int sum=1;
    if(n==1)
        sum*=1;
    else
        sum=n*factorialRecursive(n-1);
    // return sum;   // 去掉这里的return语句
}

int factorialIteration(int product, int counter, int max_count)
{
    int sum=1;
    if(counter>max_count)
        return sum*=product;   // 在这里加上return语句
    else
        factorialIteration((counter*product),(counter+1),max_count);
}

现在来看另一个问题:

#include <iostream>
using namespace std;

int test(int n);
int sum;

int main()
{
    cout<<test(1)<<endl;
    return 0;
}
int test(int n)
{
    sum = 1;
    sum += n;
    if (sum < 5)   
        test(n+1);
}

如果设sum为全局变量,那么会在test函数中每一次调用sum=1时都将sum重新赋值为1。整个程序最后输出为5。这个应该没有什么悬念吧?

如果设sum给test内的局部变量,则会在每一次执行int sum=1语句时都会创建一个新的sum对象,它的存放地址和之前的sum并不相同。然后整个程序最后输出意外的是4。

#include <iostream>
using namespace std;

int test(int n);

int main()
{
    cout<<test(1)<<endl;
    return 0;
}
int test(int n)
{
    int sum = 1;
    sum += n;
    if (sum < 5)
        return test(n+1);
    // return sum;   此处有这一行代码命名为程序1,没有这行代码命名为程序2
}

程序1的输出是5,程序2的输出是4。具体函数执行过程如下:

第一步,调用test(1):

int sum=1
sum=2
return test(2)

第二步,调用test(2):

int sum=1
sum=3
return test(3)

第三步,调用test(3):

int sum=1
sum=4
return test(4)

第四步,调用test(4):

int sum=1
sum=5

执行到第四步的时候,由于sum以及不比5小了,所以程序1没有进入if语句而是执行下一句return sum,所以输出为1。

而如果是程序2,也就是没有return sum语句,那么程序在执行完第四步后就会返回到第三步,最终调用(return) sum=4,输出4。


第三个问题:

该童鞋还提到了尾递归,这里我就来说说我的理解,如有问题欢迎大家直接评论或邮件给我。

上面代码中的递归函数factorialRecursive应该没问题的吧。

上面的代码我给其命名为迭代。

int factorialIteration(int product, int counter, int max_count)
{
    int sum=1;
    if(counter>max_count)
        sum*=product;
    else
        factorialIteration((counter*product),(counter+1),max_count);
}

通过在main函数中调用如下代码来执行该函数:

cout<<factorialIteration(1,1,n)<<endl;

当然,也可以另外写一个函数如下:

int factorialIter(int n)
{
    return factorialIteration(1,1,n);
}

并通过在main函数中直接调用该函数来做计算:

cout<<factorialIter(n)<<endl;

函数factorialIteration中的max_count我们称其为“循环不变量”,也就是对于整个运算过程而言这个变量是不变的。为了让大家更加印象深刻,将前面出现过的东西再来复制一遍:

(factorial 6)
(factorial 1 1 6)
(factorial 1 2 6)
(factorial 2 3 6)
(factorial 6 4 6)
(factorial 24 5 6)
(factorial 120 6 6)
(factorial 720 7 6)
720

从第二行开始的factorial的第三个参数”6“就是循环不变量。

尾递归&

  • 9
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值