递归调用层数太多_算法基础:递归算法知识笔记

=2,n∈N*)。","27:\"11\""],[20,"\n","24:\"thYy\""],[20,"public static int fibonacci(int n) {"],[20,"\n","24:\"COa3\""],[20,"        if (n == 1 || n == 2) {     // 递归终止条件"],[20,"\n","24:\"y8AD\""],[20,"            return 1;       // 简单情景"],[20,"\n","24:\"AsST\""],[20,"        }"],[20,"\n","24:\"luzy\""],[20,"        return fibonacci(n - 1) + fibonacci(n - 2); // 相同重复逻辑,缩小问题的规模"],[20,"\n","24:\"9PNJ\""],[20,"}"],[20,"\n","24:\"DaoT\""],[20,"4.3 汉诺塔问题"],[20,"\n","24:\"6qkm\"|32:3"],[20,"/** "],[20,"\n","24:\"hEWQ\""],[20,"* Title: 汉诺塔问题 "],[20,"\n","24:\"XLwD\""],[20,"* Description:古代有一个梵塔,塔内有三个座A、B、C,A座上有64个盘子,盘子大小不等,大的在下,小的在上。 "],[20,"\n","24:\"W9JY\""],[20,"* 有一个和尚想把这64个盘子从A座移到C座,但每次只能允许移动一个盘子,并且在移动过程中,3个座上的盘子始终保持大盘在下, "],[20,"\n","24:\"v9Ll\""],[20,"* 小盘在上。在移动过程中可以利用B座。要求输入层数,运算后输出每步是如何移动的。 "],[20,"\n","24:\"uRRl\""],[20,"* "],[20,"\n","24:\"iScv\""],[20," */"],[20,"\n","24:\"kV5q\""],[20,"public class HanoiTower {"],[20,"\n","24:\"RAwb\""],[20," "],[20,"\n","24:\"koAg\""],[20,"    /**     "],[20,"\n","24:\"FAoG\""],[20,"     * @description 在程序中,我们把最上面的盘子称为第一个盘子,把最下面的盘子称为第N个盘子"],[20,"\n","24:\"SRiX\""],[20,"     * @author rico       "],[20,"\n","24:\"DqPu\""],[20,"     * @param level:盘子的个数"],[20,"\n","24:\"ohiT\""],[20,"     * @param from 盘子的初始地址"],[20,"\n","24:\"KOCp\""],[20,"     * @param inter 转移盘子时用于中转"],[20,"\n","24:\"OYaK\""],[20,"     * @param to 盘子的目的地址"],[20,"\n","24:\"2paR\""],[20,"     */"],[20,"\n","24:\"R1w2\""],[20,"    public static void moveDish(int level, char from, char inter, char to) {"],[20,"\n","24:\"6zKZ\""],[20," "],[20,"\n","24:\"Xj96\""],[20,"        if (level == 1) { // 递归终止条件"],[20,"\n","24:\"HHq1\""],[20,"            System.out.println(\"从\" + from + \" 移动盘子\" + level + \" 号到\" + to);"],[20,"\n","24:\"gCjy\""],[20,"        } else {"],[20,"\n","24:\"bZq1\""],[20,"            // 递归调用:将level-1个盘子从from移到inter(不是一次性移动,每次只能移动一个盘子,其中to用于周转)"],[20,"\n","24:\"cU6o\""],[20,"            moveDish(level - 1, from, to, inter); // 递归调用,缩小问题的规模"],[20,"\n","24:\"gnlp\""],[20,"            // 将第level个盘子从A座移到C座"],[20,"\n","24:\"JEZ8\""],[20,"            System.out.println(\"从\" + from + \" 移动盘子\" + level + \" 号到\" + to); "],[20,"\n","24:\"Fmf9\""],[20,"            // 递归调用:将level-1个盘子从inter移到to,from 用于周转"],[20,"\n","24:\"kU9b\""],[20,"            moveDish(level - 1, inter, from, to); // 递归调用,缩小问题的规模"],[20,"\n","24:\"XObT\""],[20,"        }"],[20,"\n","24:\"aSAQ\""],[20,"    }"],[20,"\n","24:\"Ahfh\""],[20," "],[20,"\n","24:\"J0Mu\""],[20,"    public static void main(String[] args) {"],[20,"\n","24:\"ktdN\""],[20,"        int nDisks = 30;"],[20,"\n","24:\"eC6F\""],[20,"        moveDish(nDisks, 'A', 'B', 'C');"],[20,"\n","24:\"KVX9\""],[20,"    }"],[20,"\n","24:\"7sej\""],[20,"4.4 二叉树深度 "],[20,"\n","24:\"Wwky\"|32:3"],[20,"public static int getTreeDepth(Tree t) { "],[20,"\n","24:\"xpxF\""],[20,"        // 树为空"],[20,"\n","24:\"THrq\""],[20,"        if (t == null) // 递归终止条件"],[20,"\n","24:\"8s0W\""],[20,"            return 0; "],[20,"\n","24:\"2stF\""],[20,"        int left = getTreeDepth(t.left); // 递归求左子树深度,缩小问题的规模"],[20,"\n","24:\"BBpe\""],[20,"        int right = getTreeDepth(t.left); // 递归求右子树深度,缩小问题的规模 "],[20,"\n","24:\"0ccn\""],[20,"        return left > right ? left + 1 : right + 1;"],[20,"\n","24:\"0eJi\""],[20,"    }"],[20,"\n","24:\"e5kA\""],[20,"\n","24:\"YlZH\""],[20,"\n","24:\"qn1p\""],[20,"\n","24:\"XHgC\"|32:2"],[20,"\n","24:\"dxXV\""]]">

1、递归算法定义

递归算法是将重复问题分解为同类的子问题而解决问题的方法,其核心思想是分治策略。

简单来说就是自己调用自己。直到达到退出递归的条件,则完成递归。

2、递归的步骤

1、找整个递归的终止条件:递归应该在什么时候结束?

2、找返回值:应该给上一级返回什么信息?

3、本级递归应该做什么:在这一级递归中,应该完成什么任务?

3、递归的优点和缺点

优点:递归的核心思想就是将一个大问题,拆解成一个小问题,然后将小问题再次拆解,层层拆分从而简化问题的实现。从而达到简化重复的代码让程序变得更加简洁。

缺点:使用递归算法时每次方法的调用都需要在栈中开辟出一个空间保存相关数据,频繁的压栈、弹栈会导致效率变低。

4、递归的案例

4.1 阶乘的算法

    // 阶乘的递归实现

    public static long f(int n){

        if(n == 1)   // 结束递归终止条件 

            return 1;   

        return n*f(n-1);  // 相同重复逻辑,缩小问题的规模

    }

4.2 斐波纳契数列

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

在数学上,斐波纳契数列以如下被以递归的方法定义:F0=0,F1=1,Fn=F(n-1)+F(n-2)(n>=2,n∈N*)。

public static int fibonacci(int n) {

        if (n == 1 || n == 2) {     // 递归终止条件

            return 1;       // 简单情景

        }

        return fibonacci(n - 1) + fibonacci(n - 2); // 相同重复逻辑,缩小问题的规模

}

4.3  汉诺塔问题

/** 

* Title: 汉诺塔问题 

* Description:古代有一个梵塔,塔内有三个座A、B、C,A座上有64个盘子,盘子大小不等,大的在下,小的在上。 

* 有一个和尚想把这64个盘子从A座移到C座,但每次只能允许移动一个盘子,并且在移动过程中,3个座上的盘子始终保持大盘在下, 

* 小盘在上。在移动过程中可以利用B座。要求输入层数,运算后输出每步是如何移动的。 

 */

public class HanoiTower {

    /**     

     * @description 在程序中,我们把最上面的盘子称为第一个盘子,把最下面的盘子称为第N个盘子

     * @author rico       

     * @param level:盘子的个数

     * @param from 盘子的初始地址

     * @param inter 转移盘子时用于中转

     * @param to 盘子的目的地址

     */

    public static void moveDish(int level, char from, char inter, char to) {

        if (level == 1) { // 递归终止条件

            System.out.println("从" + from + " 移动盘子" + level + " 号到" + to);

        } else {

            // 递归调用:将level-1个盘子从from移到inter(不是一次性移动,每次只能移动一个盘子,其中to用于周转)

            moveDish(level - 1, from, to, inter); // 递归调用,缩小问题的规模

            // 将第level个盘子从A座移到C座

            System.out.println("从" + from + " 移动盘子" + level + " 号到" + to); 

            // 递归调用:将level-1个盘子从inter移到to,from 用于周转

            moveDish(level - 1, inter, from, to); // 递归调用,缩小问题的规模

        }

    }

    public static void main(String[] args) {

        int nDisks = 30;

        moveDish(nDisks, 'A', 'B', 'C');

    }

4.4 二叉树深度 

public static int getTreeDepth(Tree t) { 

        // 树为空

        if (t == null) // 递归终止条件

            return 0; 

        int left = getTreeDepth(t.left); // 递归求左子树深度,缩小问题的规模

        int right = getTreeDepth(t.left); // 递归求右子树深度,缩小问题的规模 

        return left > right ? left + 1 : right + 1;

    }

IT技术分享社区

个人博客网站:https://programmerblog.xyz

5ea014e7522375a6f7d85ff61d14344c.png

文章推荐 程序员效率:画流程图常用的工具 程序员效率:整理常用的在线笔记软件 远程办公:常用的远程协助软件,你都知道吗? 51单片机程序下载、ISP及串口基础知识 硬件:断路器、接触器、继电器基础知识

 1、递归算法定义

递归算法是将重复问题分解为同类的子问题而解决问题的方法,其核心思想是分治策略。

简单来说就是自己调用自己。直到达到退出递归的条件,则完成递归。

2、递归的步骤

1、找整个递归的终止条件:递归应该在什么时候结束?

2、找返回值:应该给上一级返回什么信息?

3、本级递归应该做什么:在这一级递归中,应该完成什么任务?

3、递归的优点和缺点

优点:递归的核心思想就是将一个大问题,拆解成一个小问题,然后将小问题再次拆解,层层拆分从而简化问题的实现。从而达到简化重复的代码让程序变得更加简洁。

缺点:使用递归算法时每次方法的调用都需要在栈中开辟出一个空间保存相关数据,频繁的压栈、弹栈会导致效率变低。

4、递归的案例

4.1 阶乘的算法

    // 阶乘的递归实现

    public static long f(int n){

        if(n == 1)   // 结束递归终止条件 

            return 1;   

        return n*f(n-1);  // 相同重复逻辑,缩小问题的规模

    }

4.2 斐波纳契数列

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

在数学上,斐波纳契数列以如下被以递归的方法定义:F0=0,F1=1,Fn=F(n-1)+F(n-2)(n>=2,n∈N*)。

public static int fibonacci(int n) {

        if (n == 1 || n == 2) {     // 递归终止条件

            return 1;       // 简单情景

        }

        return fibonacci(n - 1) + fibonacci(n - 2); // 相同重复逻辑,缩小问题的规模

}

4.3  汉诺塔问题

/** 

* Title: 汉诺塔问题 

* Description:古代有一个梵塔,塔内有三个座A、B、C,A座上有64个盘子,盘子大小不等,大的在下,小的在上。 

* 有一个和尚想把这64个盘子从A座移到C座,但每次只能允许移动一个盘子,并且在移动过程中,3个座上的盘子始终保持大盘在下, 

* 小盘在上。在移动过程中可以利用B座。要求输入层数,运算后输出每步是如何移动的。 

 */

public class HanoiTower {

    /**     

     * @description 在程序中,我们把最上面的盘子称为第一个盘子,把最下面的盘子称为第N个盘子

     * @author rico       

     * @param level:盘子的个数

     * @param from 盘子的初始地址

     * @param inter 转移盘子时用于中转

     * @param to 盘子的目的地址

     */

    public static void moveDish(int level, char from, char inter, char to) {

        if (level == 1) { // 递归终止条件

            System.out.println("从" + from + " 移动盘子" + level + " 号到" + to);

        } else {

            // 递归调用:将level-1个盘子从from移到inter(不是一次性移动,每次只能移动一个盘子,其中to用于周转)

            moveDish(level - 1, from, to, inter); // 递归调用,缩小问题的规模

            // 将第level个盘子从A座移到C座

            System.out.println("从" + from + " 移动盘子" + level + " 号到" + to); 

            // 递归调用:将level-1个盘子从inter移到to,from 用于周转

            moveDish(level - 1, inter, from, to); // 递归调用,缩小问题的规模

        }

    }

    public static void main(String[] args) {

        int nDisks = 30;

        moveDish(nDisks, 'A', 'B', 'C');

    }

4.4 二叉树深度 

public static int getTreeDepth(Tree t) { 

        // 树为空

        if (t == null) // 递归终止条件

            return 0; 

        int left = getTreeDepth(t.left); // 递归求左子树深度,缩小问题的规模

        int right = getTreeDepth(t.left); // 递归求右子树深度,缩小问题的规模 

        return left > right ? left + 1 : right + 1;

    }

IT技术分享社区

个人博客网站:https://programmerblog.xyz

5ea014e7522375a6f7d85ff61d14344c.png

文章推荐 程序员效率:画流程图常用的工具 程序员效率:整理常用的在线笔记软件 远程办公:常用的远程协助软件,你都知道吗? 51单片机程序下载、ISP及串口基础知识 硬件:断路器、接触器、继电器基础知识
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值