zoukankan      html  css  js  c++  java
  • 029:Java 递归算法

    Java 递归算法

    (转自:http://c.biancheng.net/view/940.html

    1.递归概念

           程序调用自身的编程技巧称为递归(recursion),它做为一种算法在程序设计语言中广泛应用。Java 支持递归,在 Java 编程中,递归是允许方法调用自身调用的属性。调用自身的方法称为是递归的。
           递归的典型例子是数字的阶乘。数字 N 的阶乘是 1 到 N 之间所有整数的乘积。例如 3 的阶乘就是 1×2×3。下面的程序使用递归来计算数字的阶乘。

    1. public class Factorial {
    2.     int fact(int n) {
    3.         int result;
    4.         if (n == 1) {
    5.             return 1;
    6.         }
    7.         result = fact(n - 1) * n;
    8.         return result;
    9.     }

    10. }

    1. 11.  

    12. class Recursion {

    1. 13.     public static void main(String args[]) {
    2. 14.         Factorial f = new Factorial();
    3. 15.         System.out.println("3的阶乘是 " + f.fact(3));
    4. 16.         System.out.println("4的阶乘是 " + f.fact(4));
    5. 17.         System.out.println("5的阶乘是 " + f.fact(5));
    6. 18.     }

    19. }

    该程序产生的输出如下所示:

    3的阶乘是 6
    4的阶乘是 24
    5的阶乘是 120

           如果你对递归的方法比较陌生,那么 fact( ) 的操作可能看起来有点糊涂。它是这样工作的,当 fact( ) 带着参数 1 被调用时,该方法返回 1,否则它返回 fact( n-1 ) 与 n 的乘积。为了对这个表达式求值,fact( ) 带着参数 n-1 被调用。重复这个过程直到 n 等于 1,且对该方法的调用开始返回。
           为了更好地理解 fact( ) 方法是如何工作的,让我们通过一个短例子来说明。例如当计算 3 的阶乘时,对 fact( ) 的第一次调用引起参数 2 的第二次调用。这个调用将引起 fact 以参数 1的第三次调用,这个调用返回 1,这个值接着与 2(第二次调用时 n 的值)相乘。然后该结果(现为 2)返回到 fact( ) 的最初的调用,并将该结果与 3(n 的初始值)相乘。这时得到答案 6。可以在 fact( ) 中插入 println() 语句,显示每次调用的阶数以及中间结果。
           当一个方法调用它自身的时候,堆栈就会给新的局部变量和自变量分配内存,方法代码就带着这些新的变量从头执行。递归调用并不产生方法新的拷贝。只有参数是新的。每当递归调用返回时,旧的局部变量和自变量就从堆栈中清除,运行从方法中的调用点重新开始。递归方法可以说是像“望远镜”一样,可以自由伸缩。
    许多子程序的递归版本执行时会比它们的迭代版本要慢一点,因为它们增加了额外的方法调用的消耗。对一个方法太多的递归调用会引起堆栈崩溃。因为自变量和局部变量的存储都在堆栈中,每次调用都创建这些变量新的拷贝,堆栈有可能被耗尽。如果发生这种情况,Java 的运行时系统就会产生异常。但是,除非递归子程序疯狂运行,否则你大概不会担心这种情况。
           递归的主要优点在于:某些类型的算法采用递归比采用迭代算法要更加清晰和简单。例如快速排序算法按照迭代方法是很难实现的。还有其他一些问题,特别是人工智能问题,就依赖于递归提供解决方案。最后,有些人认为递归要比迭代简单。
           当编写递归方法时,你必须使用 if 条件语句在递归调用不执行时来强制方法返回。如果你不这么做,一旦你调用方法,它将永远不会返回。这类错误在使用递归时是很常见的。尽量多地使用 println() 语句,使你可以了解程序的进程。如果发现错误,立即中止程序运行。
    下面是递归的又一个例子。递归方法 printArray( ) 打印数组 values 中的前 i 个元素。

    1. class RecTest {
    2.     int values[];
    3.  
    4.     RecTest(int i) {
    5.         values = new int[i];
    6.     }
    7.  
    8.     void printArray(int i) {
    9.         if (i == 0){
    10. 10.             return;
    11. 11.         } else {
    12. 12.             printArray(i - 1);
    13. 13.         }
    14. 14.         System.out.println("[" + (i - 1) + "] " + values[i - 1]);
    15. 15.     }

    16. }

    1. 17.  

    18. class Recursion2 {

    1. 19.     public static void main(String args[]) {
    2. 20.         RecTest ob = new RecTest(10);
    3. 21.         int i;
    4. 22.         for (i = 0; i < 10; i++) {
    5. 23.             ob.values[i] = i;
    6. 24.         }
    7. 25.         ob.printArray(10);
    8. 26.     }

    27. }

    该程序产生如下的输出:

    [0] 0
    [1] 1
    [2] 2
    [3] 3
    [4] 4
    [5] 5
    [6] 6
    [7] 7
    [8] 8
    [9] 9

    本文来自博客园,作者:Jaoany,转载请注明原文链接:https://www.cnblogs.com/fanglijiao/p/15553893.html

  • 相关阅读:
    Encryption (hard) CodeForces
    cf 1163D Mysterious Code (字符串, dp)
    AC日记——大整数的因子 openjudge 1.6 13
    AC日记——计算2的N次方 openjudge 1.6 12
    Ac日记——大整数减法 openjudge 1.6 11
    AC日记——大整数加法 openjudge 1.6 10
    AC日记——组合数问题 落谷 P2822 noip2016day2T1
    AC日记——向量点积计算 openjudge 1.6 09
    AC日记——石头剪刀布 openjudge 1.6 08
    AC日记——有趣的跳跃 openjudge 1.6 07
  • 原文地址:https://www.cnblogs.com/fanglijiao/p/15553893.html
Copyright © 2011-2022 走看看