• 数据结构之递归


    ------------恢复内容开始------------

    ------------恢复内容开始------------

    1.什么是递归

    • 在java中,递归就是方法直接或者间接的调用自己本身。
    • 核心思想:就是分治算法,将大问题分解成小问题求解
    • 优缺点
      优点 缺点
      代码简洁、可读性好

      递归调用,占用空间大

      递归太深,容易发生堆栈溢出

      容易出现重复计算

    2.常用的递归场景:

    • 各种数学问题,如八皇后问题、汉诺塔、阶乘问题、迷宫问题以及球和篮子的问题
    • 各种算法问题,如归并排序、快速排序、二分查找、分治算法等
    • 将栈解决的问题转化为递归解决的问题

    3.递归使用需要满足的三个条件:

    • 存在截止条件,即有明确的递归结束条件
    • 求出递归公式
    • 可以将大问题分成若干个小问题,每个小问题的求解思路和大问题一样,除了数据规模上存在差异

    4.递归常见的思维误区以及注意事项

    • 不要尝试利用大脑将递归的每一步都搞清楚,这将会越搞越乱。我们只需要明确递归两要素即可:递归结束条件和递归公式
    • 每次执行一个方法时,会创建一个新的受保护的独立栈空间
    • 方法的局部变量是相互独立的,不存在相互影响。其中,若局部变量是引用类型(数组),则会共享该引用类型的数据

    5.递归常见的问题

    • 堆栈溢出
    • 产生原因:函数调用时,会将临时变量存储到堆栈中。每次调用,都会将临时变量保存到栈中。而系统站或者虚拟机栈的空间有限。如果求解数据规模太大,会造成堆栈溢出,进而导致系统崩溃
    • 解决方法:   1. 限制递归深度。局限:当前栈内存空间的大小与当前线程剩余的占空间大小有关,无法事先估算,只适用于递归深度比较小的场景。

    2.将递归代码改成非递归代码,即循环迭代(递归的天敌和好友)。不需要额外的空间和时间

    • 存在重复计算
    • 解决方法:利用散列表,保存已经调用过的函数,然后每次调用会先进行检查
    • 时间和空间复杂度高:
    • 解决方法:改成迭代循环

    6.递归的优化

    • 重复计算的优化:利用散列表
    • 利用尾递归进行优化:函数调用时,直接返回调用结果,然后把调用结果当作参数,放入到函数中。避免对局部变量的存储。例如
    用线性递归实现Fibonacci函数:
    1 public int
    FibonacciRecursive(int n) 2 { 3 if( n < 2) 4 return n; 5 return (FibonacciRecursive(n-1)+FibonacciRecursive(n-2)); 6 }
    用尾递归来实现
    Fibonacci函数:
    public int
    FibonacciRecursive(int n,int a,int b){
      if(n == 0){
        return 0;
    }
    return
    FibonacciRecursive(n - 1,b,a + b);}
    优点:不需要返回去,省区了对栈内存的消耗。


    ------------恢复内容结束------------

    ------------恢复内容结束------------

    ------------恢复内容结束------------

  • 相关阅读:
    SQLite3 of python
    爬虫半成品
    python初体验 ——>>> 模拟体育竞技
    文件操作
    numpy 库简单使用
    numpy 与 matplotlib 的应用
    面向对象的详细解读
    使用python进行微信好友分析
    我的第一个爬虫实验
    排球训练营
  • 原文地址:https://www.cnblogs.com/zyj-0917/p/12672441.html
Copyright © 2020-2023  润新知