• 10-递归


    1. 概述

    • 递归就是方法在内部调用自己本身,和调别起的方法没区别
    • 递归需要遵守的重要规则
      • 执行一个方法时,就创建一个新的受保护的独立空间(栈空间)
      • 方法的局部变量是独立的,不会相互影响;但如果方法中使用的是引用类型变量(比如数组),就会共享该引用类型的数据
      • 递归必须向退出递归的条件逼近,即该函数所处理的数据规模必须在递减,否则就是无限递归,出现 StackOverflowError
      • 当一个方法执行完毕,或者遇到 return,就会返回,遵守谁调用,就将结果返回给谁,同时当方法执行完毕或者返回时,该方法也就执行完毕
    • 一个应用场景:迷宫问题(回溯)

    2. 理解“方法调用”过程

    • 当在一个函数运行期间,调用另一个函数时,在运行被调用函数之前,系统需要先完成 3 件事
      • 将所有实参,返回地址等信息传递给被调用函数保存
      • 为被调用函数的局部变量分配存储区
      • 将控制转移到被调函数的入口
    • 从被调用函数返回调用函数之前,系统也应完成 3 件工作
      • 保存被调函数的计算结果
      • 释放被调函数的数据区
      • 依照被调函数保存的返回地址将控制转移到调用函数
    • 当有多个函数构成嵌套调用时,按照"后调用先返回"的原则
      • 上述函数之间的信息传递和控制转移必须通过"栈"来实现,即系统将整个程序运行时所需的数据空间安排在一个栈中
      • 每当调用一个函数,就为它在栈顶分配一个存储区
      • 每当从一个函数退出时,就释放它的存储区,则当前正运行的函数的数据区必在栈顶

    补充:https://www.jianshu.com/p/e7a22923867f

    • 当在一个函数运行期间,调用另一个函数时,在运行被调用函数之前,系统需要先完成 3 件事
      • 将所有实参,返回地址等信息传递给被调用函数保存
      • 为被调用函数的局部变量分配存储区
      • 将控制转移到被调函数的入口
    • 从被调用函数返回调用函数之前,系统也应完成 3 件工作
      • 保存被调函数的计算结果
      • 释放被调函数的数据区
      • 依照被调函数保存的返回地址将控制转移到调用函数
    • 当有多个函数构成嵌套调用时,按照"后调用先返回"的原则
      • 上述函数之间的信息传递和控制转移必须通过"栈"来实现,即系统将整个程序运行时所需的数据空间安排在一个栈中
      • 每当调用一个函数,就为它在栈顶分配一个存储区
      • 每当从一个函数退出时,就释放它的存储区,则当前正运行的函数的数据区必在栈顶

    补充:https://www.jianshu.com/p/e7a22923867f

    3. 案例

    3.1 阶乘

    public static int factorial(int n) {
        if (n == 1) return 1;
        else return factorial(n-1) * n;
    }
    

    3.2 汉诺塔

    public static void move(int dish, char x, char y) {
        System.out.printf("[%d]: %c -> %c
    ", dish, x, y);
    }
    
    public static void hanoi(int n, char a, char b, char c) {
        if (n == 1) {
            move(n, a, c);
        } else { // 这 [n-1个盘子] 要看作一个整体
            hanoi(n-1, a, c, b); // 从a - 借助c - 到b
            move(n, a, c);
            hanoi(n-1, b, a, c); // 从b - 借助a - 到c
        }
    }
    

    4. 递归能解决什么样的问题

    使用递归解决问题的思路:[ 规模为 n 的问题 ] 的解决要借助于 [ 规模为 n-1 的问题 ] 的解决

    • 各种数学问题:八皇后问题,汉诺塔,阶乘问题,迷宫问题,球和篮子的问题
    • 各种算法中也会使用到递归,比如快排,归并排序,二分查找,分治算法等
    • 需要用栈解决的问题 // 递归代码比较简洁
  • 相关阅读:
    bzoj [POI2015]Myjnie
    bzoj2217 [Poi2011]Lollipop
    Codeforces A Mist of Florescence
    bzoj4380 [POI2015]Myjnie
    bzoj4292 [PA2015]Równanie
    bzoj 3517翻硬币
    模块补充
    python解释器
    __file__、__name__、__dict__方法整理
    软件开发规范
  • 原文地址:https://www.cnblogs.com/liujiaqi1101/p/12237680.html
Copyright © 2020-2023  润新知