这一周的算法的学习

        这周对于算法开始了相对系统的学习,嗯,也算是弥补一下自己之前的不足,劣势;

从递归开始吧:

递归, 与循环,二者在理论上是等价的,一般的递归,我们也总可以,将其表示为循环的格式,任何循环同样也可以改写成递归的形式,这里是一些循环改写递归的方法与例子:

听说哈,有的语言是没有递归的;

递归的改写,重要的是,发现循环之中的相似性;

下面是实例:



  1. //打印从0到9的整数;
  2. #include <stdio.h>
  3. #include <conio.h>
  4. void main()
  5. {
  6. for (int i = 0; i < 10; i++)
  7. {
  8. printf("%d\n",i);
  9. }
  10. _getch();
  11. }


这样就是一个初步的循环输出的样式,现在要改写为递归的格式,该如何改变。

递归,之前听有一位老师讲过,实质上始终踢皮球的做法

以上面这个例字来假设,要想打印从0-9的整数,想象,这个工作,被推到我身上,但是我又不能原封不动地将所有工作交给下属,我多少得做一些,所以,我可以这么干:

定义一个函数,打印一个数字;

  1. int  print(int n)
  2. {
  3.     f(n-1);//打印0-(n-1)
  4.     printf("%d",n);//打印n
  5. }

 就是我干一部分工作,比如说我打印n,将剩下的所有工作推给下属,然后,同理,下属也是想要推卸责任,下属只打印了n-1的那一份,又将剩下的工作推给下属的下属………………以此类推

但是,这里就出现了递归的一个限制,凡是递归,实质上是函数不断调用自身的做法,如果这么无限次调用下去,那就是死循环,我们要考虑如何从这个递归的死循环里跳出来,就 

是,找到出口


  1. int  f(int n)
  2. {
  3. if (n>0)
  4. {
  5. f(n - 1);//打印0-(n-1)
  6. printf("%d", n);//打印n
  7. }

这里加入了一个限制,限制了n的取值,当n>0的时候,递归才能继续调用。

当然如果没有相似性,就需要我们主动构造相似性,有一些循环不能找到相似性的原因可能是缺少参数,这个时候就需要找到一个参数作为函数调用之间的桥梁,保证其相似性,构造递归

复杂一点的例子:

 数组所有元素求和

原:

  1. #include <stdio.h>
  2. #include <conio.h>
  3. #define N 10

  4. int add(int a[]);

  5. void main()
  6. {
  7. int a[N] = { 2,5,3,9,12,7 };
  8. int sum;
  9. sum = add(a);
  10. printf("%d\n", sum);
  11.         _getch();
  12. }
  13. int add(int a[])
  14. {
  15. int x = 0;
  16. for (int i = 0; i < N; i++)
  17. {
  18. x += a[i];
  19. }
  20. return x;
  21. }

这里要想将这个循环改写成递归的形式,做法如下:

  1. int f(int a[],int begin)            //求a数组中从begin开始到结束的元素和
  2. {
  3. if(begin==N)        return 0;
  4. int x= f(a,begin+1);
  5. return x + a[begin];
  6. }
  7.  void main()
  8. {
  9. int a[N] = { 2,5,3,9,12,7 };
  10. int sum;
  11. sum = f(a,0);//从第零项开始累加
  12. printf("%d\n", sum);
  13.  _getch(};
  14. }


这个就是一些简单的递归的变换构造的问题的做法

献丑



    f(n-1);//打印0-(n-1)

    printf("%d",n);//打印n

猜你喜欢

转载自blog.csdn.net/nightvales/article/details/80469778