递归

来源:互联网 发布:淘宝做分销有成功的吗 编辑:程序博客网 时间:2024/06/08 00:18

一、递归的定义


       当求解一个问题时,若是通过求解与它具有同样解法的、相对简化的子问题而得到的,这就是递归。一个递归的求解问题必然包含终止递归的条件,当满足一定条件时就终止继续向下递归,从而使最小问题不通过递归而解决,然后再依次返回解决较大的问题,最后解决整个问题。解决递归问题的算法称为递归算法,在递归算法中需要根据递归条件直接或间接地调用算法本身,当满足终止条件时结束递归调用。当然对于一些简单问题的递归问题,很容易把它转换为循环问题来解决,从而使编写出的算法更为有效。



二、递归应用举例

1、采用递归算法求解正整数n的阶乘(n!).

       由数学知识可知,n的阶乘的递归定义为:它等于n乘以n-1的阶乘,即n!=n*(n-1)!,并且规定1和0的阶乘为1。设函数f( n )=n!,则f( n ) 可表示为:

                                                    f(n)=1                            (n=1或n=0)

                                                    f(n)=n*f(n-1)             (n>1)


用Java语言编写出求解n!的递归函数为:

public static long f(int n){if(n==1||n==0){return 1;}else{return n*f(n-1);}}

2、编写一个算法输出n个二进制位的所有可能的编码值。

      分析:每个二进制位取0和1两个值。根据题意,当n为1时有两个编码值0和1,当n为2时有4个编码值,依次为00、01、10、11,当n为3时有8个编码值,依次为000、001、010、011、100、101、110、111。总之,对于n个二进制位,所有可能的编码值为2^n个,每个编码值都有n位。

       n个二进制位的2^n种不同的编码值可以写做2*2^(n-1),其中2^(n-1)个二进制位的所有编码值,每种包含n-1个二进制位。n个二进制位的每一种编码值是在n-1个二进制位的每个编码值的前面分别加上0或1而得到的结果,合起来正好是2*2^(n-1)=2^n种编码。由此可以看出它是一个递归的计算过程。

       设n个二进制位用一个整型数组b[n]来表示,要得到b[0]~b[n-1]这n个二进制位的每一种可能的编码,则要首先在b[0]被置0的情况下得到b[1]~b[n-1]这n-1个二进制位的每一种可能的编码,然后再b[0]被置1的情况下得到b[1]~b[n-1]这n-1个二进制位的每一种可能的编码;同理,要得到b[1]~b[n-1]这n-1个二进制位的每一种可能的编码,则要首先在b[1]被置0的情况下得到b[2]~b[n-1]这n-2个二进制位的每一种可能的编码,然后在b[1]被置1的情况下得到b[2]~b[n-1]这n-2个二进制位的每一种可能的编码;依次类推,直到最后一个二进制位b[n-1]被置0后输出整个数组值和被置1后输出整个数组值为止。

       下面是对b[0]~b[n-1]之间的n个二进制位输出其所有编码的递归算法,初始非递归调用时应把实参值0传送给形参k。

public static void coding(int b[],int k,int n){if(k==n){//终止递归,输出在b数组中排好的一个二进制数for(int i=0;i<n;i++){System.out.print(b[i]);}System.out.print(" ");}else{//把下标为k的元素置0后,从下标k-1起递归调用b[k]=0;coding(b,k+1,n);//把下标为k的元素置1后,从下标k+1起递归调用b[k]=1;coding(b,k+1,n);}}

       此算法在执行过程中需要被调用2^(n+1)-1次,其中有2^n次需要调用输出数组b中n个元素的值,所以算法的时间复杂度为O(n*2^n),该算法所使用的系统栈的最大深度为n+1,所以其空间复杂度我O(n),n为待编码的二进制位的个数。   





原创粉丝点击