递归算法的经典运用

递归(recursion):程序调用自身的编程技巧
递归满足两个条件:
(1)有反复执行的过程(调用自身)
(2)有跳出反复执行过程的条件(递归出口)

递归例子(常用的地方):
(1)阶乘
n != n * (n – 1) * (n – 2) * …* 1 (n > 0)
程序:

   #include <stdio.h>

   int recursive(int i)
   {
       int sum;
       if(0 == i)
           return 1;
       else
           sum = i * recursive(i - 1); // i * (i - 1) * .... * 1

       return sum;
   } 

   int main()
   {
       int temp;

       temp = recursive(5);

       printf("temp = %d\n",temp);
   }

(2)河内塔问题
分析:汉诺塔的算法3个步骤:
第一,把a上n-1个盘通过c移动到b。
第二,把a上最下面的盘移到c。
第三,因为n-1盘全在b上了,所以把b当做a重复以上步骤就好了。
所以把b当做a重复以上步骤就好了。
算法看起来简单,但是思考的过程很复杂,难以理解。递归中会保存数据好处在这里有得到体现。

    #include <stdio.h>

    int count = 0;

    //定义函数n是要移动的个数,a移动到c通过b
    void hanoi(int n,int a,int b,int c)
    {   
        if(n >= 1)
        {
            hanoi(n-1,a,c,b); //n - 1 move to b by c
            printf("%c--%c\n",a,c);//print process
            count++;
            hanoi(n-1,b,a,c);  //move to c by a
        }
    }

    int main()
    {   
        int n;
        printf("Input the number of diskes:\n");
        scanf("%d",&n);
        hanoi(n,'A','B','C');
        printf("count = %d\n",count);
    }

对递归的一些理解:
解决问题、不能太去关心细节(因为递归的过程恰恰是我们实现的方法)就像中国问题,如果我们在第一步就过多的纠结于如何把n-1移动到B上,那么你的思路就很难继续深入。只要看做是用函数实现就好,如果你看出不管怎么移动其实本质都一样的时候,那么久能较快的得到结果了。

思考问题讲究思路的连贯性、力求尽快进入状态,享受完全投入到一件事中的每秒感觉。

(3)全排列
从n个不同元素中任取m(m <= n)个元素,按照一定的顺序排列起来,叫做从不同元素中取出m个元素的一个排列,当m = n所有的排列情况就叫全排列。

如1、2、3三个元素全排列为:
1,2,3
1,3,2
2,1,3
2,3,1
3,1,2
3,2,1

全排列有两种算法:
一种是递归,一种是非递归。
递归算法的思路比较接近于我们现实生活中的思路。
1、试想,如果我们只有两个数字:12,要对它进行排列,第一种就是12本身,第二种,将12交换,变为21.

2、但是如果我们要对123进行全排列。我们可以采用将1固定,“23”进行全排列,将“2”固定,对“13”进行全排列。将“3”固定,对“12”进行全排列。
其实这就是首部为“1”,然后是“2”,然后是“3”,不就是第二位后边的数依次和第一位进行交换么?

3.但是这样也不全面,我们每次交换要将排列恢复成原来的“123”,因为这个算法求排列的时候,前后并没有依赖性,其参考物只有“123”这个原始的第一个排列。否则,我们不恢复的话,就会出现,虽然数量与正确解法相同,但是会有重复排列的现象。

(4)斐波那契数列
斐波那契数列,又称黄金分割数列,指的是这样一个数列:1、1、2、3、5、8、13、21….

   #include <stdio.h>

   long fob(int n)
   {
       if(n == 0)
       {
           return 0;
       }
       if(n == 1)
       {
           return 1;
       }
       if(n > 1)
       {
           return fob(n-1) + fob(n - 2);
       }
   }

   int main()
   {
       int i;
       int result;

       printf("please input number:\n");

       scanf("%d",&i);

       result = fob(i);
       printf("result = %d",result);

   }
    原文作者:递归算法
    原文地址: https://blog.csdn.net/oreo_go/article/details/51034357
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞