一道循环递归笔试题

来源:互联网 发布:男性特点知乎 编辑:程序博客网 时间:2024/05/29 19:57

前几天到复旦大学参加了DENA的宣讲会,有一道循环递归的题要求写出运行结果,当时还感觉挺简单 没想到回去把代码编译运行一遍,发现错了···,唉,感觉自己在算法方面还是太弱了点,故写这篇博客分析一下,当做自己的学习笔记吧,如果有错希望大家指出来,谢谢。

题目的代码如下:

void sub(int a[], int n){   if(n > 1)  {      for(int i = 0; i < n - 1; i ++)     {          a[i] = a[i] + a[i + 1];          sub(a, n - 1);      }   }}int main(){int a[] = {0, 1, 2, 3};sub(a, 4);}求运行结束后第二个元素的值为多少

这个题目的难点主要是在递归的基础上又增加了循环,很容易被绕晕,所以分析起来可能难一点···

分析这个函数的运行过程:

1、判断n是否大于1,如果n > 1执行第2步,否则返回(对于递归来说就是返回上一层函数中了)

2、int  i从 0  到  n - 2循环做以下两步

     a、a[i] = a[i] + a[i + 1];

     b、将n 减1,再次调用这个函数


分析过程:

1、对于 sub(a, 4) ,循环3次,从i = 0 到 i =2,调用3次sub(a,3);

2、对于 sub(a, 3) ,循环2次,从i = 0 到 i =1,调用2次sub(a,2);

3、对于 sub(a, 2) ,循环1次,从i = 0 到 i =0,调用1次sub(a,1);

4、对于 sub(a, 1) ,循环0次,什么也不干,返回上一层。


也许画个图会更容易理解一点:


(注:第三行和第四行的每一步都有a[i] = a[i] + a[i + 1]; 因为图太小不好全部写上去)

有了图就更容易分析程序是怎么运行的了。

对于int a[] = {0, 1, 2, 3};

当调用 sub(a, 4)时,进入第图上的1步,根据上面归纳的函数运行过程:

1、进入 i 从 0 到 2的循环,从 0 开始,执行a[i] = a[i] + a[i + 1,即a[0] = a[0] + a[1] ];此时数组变为{1,1,2,3};

      然后调用sub(a,3),此时进入一下层递归。

2、进入sub(a, 3)这一层,就是图中标示的第2步,

       同理,进入i 从 0 到 1的循环,从 0 开始,执行a[i] = a[i] + a[i + 1,即a[0] = a[0] + a[1] ];此时数组变为{2,1,2,3};

       然后调用sub(a,2),此时进入一下层递归。

3、进入sub(a, 2)这一层,就是图中标示的第3步,

       同理,进入i 从 0 到 0的循环,从 0 开始,执行a[i] = a[i] + a[i + 1,即a[0] = a[0] + a[1] ];此时数组变为{3,1,2,3};

       然后调用sub(a,1),此时进入一下层递归。

4、进入sub(a,1)这一层,因为该递归函数的边界条件为n > 1,调用sub(a, 1)已经达到了边界条件,什么都不会做,返回上一层。

5、上一层递归函数为sub(a, 2),sub(a,2)的循环次数只有1次(for int i = 0; i < n - 1; i ++),从0 到 0,已经执行完毕,继续返回上一层;

6、上一层递归函数为sub(a, 3),sub(a,2)的循环次数有2次,所以执行图中第4步,执行a[i] = a[i] + a[i + 1,即a[1] = a[1] + a[2] ];此时数组变为{3,3,2,3};

       然后调用sub(a, 2),此时进入一下层递归。

7、重复3、4、5步骤(重复第三步骤时数组变为{6,3,2,3}),此时返回到sub(a, 3); sub ( a, 3)的循环次数也执行完毕了,继续返回上一层。

8、上一层递归函数为sub(a, 4);此时i=1,进入图中的第6步,执行a[i] = a[i] + a[i + 1,即a[1] = a[1] + a[2] ];此时数组变为{6,5,2,3};

         然后调用sub(a, 2),此时进入一下层递归。

9、后面的步骤基本上就是重复之前的步骤了,很容易分析得出数组的变化情况如下:

{1,1,2,3}

{2,1,2,3}

{3,1,2,3}

{3,3,2,3}

{6,2,2,3}

{6,5,2,3}

{11,5,2,3}

{16,5,2,3}

{16,7,2,3}

{23,7,2,3}

{23,7,5,3}

{30,7,5,3}

{37,7,5,3}

{37,12,5,3}

{49,12,5,3}

所以执行完毕后第二个元素变为12.。

0 0