精华内容
下载资源
问答
  • 递归调用

    2019-09-26 22:50:12
    1、递归调用递归调用就是在当前的函数中调用当前的函数并传给相应的参数,这是一个动作,这一动作是层层进行的,直到满足一般情况的的时候,才停止递归调用,开始从最后一个递归调用返回。 2、递归调用的方法...

    1、递归调用:
    递归调用就是在当前的函数中调用当前的函数并传给相应的参数,这是一个动作,这一动作是层层进行的,直到满足一般情况的的时候,才停止递归调用,开始从最后一个递归调用返回。

    2、递归调用的方法计算4的阶乘为例代码如下:

    /**
    * 用递归算4的阶乘
    */
    public class Factorial {
        public static void main(String[] args) {
           //对factorial方法进行调用 
           factorial(4);
        }
        //定义方法
        public static int factorial(int n) {
            if (n == 0) {
                System.out.println(n + "! = 0");
                return 1;
            } else {
                System.out.println(n);
                //用递归的方法进行阶乘处理
                int temp = n*factorial(n-1);
                System.out.println(n + "! = " + temp);
                return temp;
            }
        }
    }
    运行结果:
    4
    3
    2
    1
    0! = 0
    1! = 1
    2! = 2
    3! = 6
    4! = 24
    

    3、4的阶乘递归图解如下:
    在这里插入图片描述

    展开全文
  • 汉诺塔递归调用(C语言实现)

    万次阅读 多人点赞 2018-11-03 14:17:09
    1.递归算法 递归算法:是一种直接或者间接地调用自身的算法。在计算机编写程序中,...然后递归调用函数(或过程)来表示问题 递归算法解决问题的特点:  (1)递归就是在过程或函数里调用自身。  (2)在使用递归策...

    预备知识

    1.递归算法

    递归算法:是一种直接或者间接地调用自身的算法。在计算机编写程序中,递归算法对解决一大类问题是十分有效的,它往往使算法的描述简洁而且易于理解。

    递归过程一般通过函数或子过程来实现。

    递归算法的实质:是把问题转化为规模缩小了的同类问题的子问题。然后递归调用函数(或过程)来表示问题

    递归算法解决问题的特点:

      (1) 递归就是在过程或函数里调用自身。

      (2) 在使用递归策略时,必须有一个明确的递归结束条件,称为递归出口。

      (3) 递归算法解题通常显得很简洁,但递归算法解题的运行效率较低。所以一般不提倡用递归算法设计程序。

      (4) 在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储。递归次数过多容易造成栈溢出等。所以一般不提倡用递归算法设计程序。

    递归的原理,其实就是一个栈(stack), 比如求5的阶乘,要知道5的阶乘,就要知道4的阶乘,4又要是到3的,以此类推,所以递归式就先把5的阶乘表示入栈, 在把4的入栈,直到最后一个,之后呢在从1开始出栈, 看起来很麻烦,确实很麻烦,他的好处就是写起代码来,十分的快,而且代码简洁,其他就没什么好处了,运行效率出奇的慢.

    导入汉诺塔问题:

    动态演示:

    汉诺塔是典型的递归问题,这个问题可以这样描述:

    完成目标:将n个block块从A搬运到C,求需要移动多少次完成?

    约束条件:搬运的过程中每次只能移动一个block块,且不能出现大的block块在小的block块之上。

     

    2.汉诺算法分析

    算分法析:

    第一次移动,要把A柱子上的前n-1个移动到B柱子上;(图1)
    第二次移动,直接把A柱子上的最后一个移动到C柱子上;(图2)
    第三次移动,把B柱子上的n-1个柱子通过柱子A移动到柱子C上。(图3)

     

     

     

     

    接着通过递归递归算法就完成了。如果第一遍没懂,仔细读三四遍应该就没问题了。

    3.实现代码

    #include <stdio.h>
    #include <string.h>
    /*
     算法思路:1将 n-1个盘子先放到B座位上
              2.将A座上地剩下的一个盘移动到C盘上
              3、将n-1个盘从B座移动到C座上
    */
    //函数声明
    void move(char x, char y);
    void hannuo(int n,char one ,char two,char three)
    {
      if(n==1)move(one, three); //递归截止条件
      else
    {
      hannuo(n-1,one ,three,two);//将 n-1个盘子先放到B座位上
      move(one,three);//将A座上地剩下的一个盘移动到C盘上
      hannuo(n-1,two,one,three);//将n-1个盘从B座移动到C座上
    
    }
    }
    void move(char x,char y)
    {
     printf("%c--->%c",x,y)
    }
    
    int main()
    {
     int n;
     printf("input your number");
     scanf("%d",&n);
     hannuo(n,'A','B','C');
     return 0;
    }

    进一步深入学习:

    https://lyl0724.github.io/2020/01/25/1/

    展开全文
  • 1.函数的递归调用 函数可以直接或者间接的调用其自身,这称为函数的递归调用。递归算法的实质是将原有的问题逐层拆解为新的问题,而解决新的问题又用到了原问题的解法,因此可以继续调用自身分解,按照此原则一直...

    1.函数的递归调用

    函数可以直接或者间接的调用其自身,这称为函数的递归调用。递归算法的实质是将原有的问题逐层拆解为新的问题,而解决新的问题又用到了原问题的解法,因此可以继续调用自身分解,按照此原则一直分解下去,每次出现的新问题都是原有问题的子集(或者说是简化版的原问题),而最终的最终分解出来的最后一个问题,一定是已知解的问题,否则没有意义。

    因此递归过程都可以用以下两个阶段概括。

    Step1:递推。所谓递推就是将原有的问题不断拆解为新的子问题,其子问题就是原有问题的弱化(或者说更少层)的问题,这样,逐渐从未知向已知推进,最终的一个子问题一定是个已知的问题,到达此后,递归阶段结束。

    Step2:回归。上一阶段递归阶段结束后,进入回归阶段,所谓回归就是从上一阶段的已知的问题出发,按照递推的过程,逐一求值回归,逐渐将未知问题都变成已知问题,一直到达递推的最开始处,结束回归阶段,问题解决。

    2.经典递归调用—汉诺塔问题

    2.1 问题描述

    有三根针A,B, C。A针上有n个盘子,盘子大小不等,大的在下,小的在上,如下图示,要把这n个盘子从A针移动到C针,在这个过程中可以借助B针,每次只允许动一个盘子,而且在移动的过程中,这三根针上都保持大盘子在下,小盘子在上。

    图2-1 汉诺塔问题示意图

     2.2 解决思路

    实际上,正如上面所说,这是一个典型的递归调用。要解决这个问题,本质上还是以上所说的递归的两个阶段。

    Step1:递归

    ①:从问题出发,我们需要达到的目标是什么:我们是想要将A上的n个盘子移动到C上

    ②:为了解决①,我们可以这么做:

    (2.1)我们可以把n-1个盘子从A针(1至n-1号盘)移至B针;

    (2.2)之后将A针中剩下的第n号盘(最下面那个)移至C针;

    (2.3)最后我们再把第2.1步中那n-1个盘子从B针全部移回至C针,至此,C针上有n个盘子,问题解决。

    经过以上三个步骤,我们把想要解决的目标问题拆分成了3个新的子问题,且这3个新的子问题都是原有的问题的弱化版或者说低层版本,我们只需要按照此一直递归,最后找到一个已知的问题即可,下面我们继续递归。

    ③:

    针对问题2.1,也就是将n-1个盘子从A针移动到B针,这个问题熟悉不熟悉?没错,这个问题他不就是我们要解决的问题(从A->C移动n个盘子)换了个目标盘(变成了从A->B)还有减少了一次次数(移动n-1个盘子)的弱化版本么?所以这个问题本身又可拆分成3个新的子问题,现在我们的目标是:我们是想要将A上的n-1个盘子移动到B上。为了解决这个问题,我们可以这么做:

    (3.1)我们可以把n-2个盘子A针(1至n-2号盘)移至C针;

    (3.2)之后将A针中剩下的第n-1号盘(最下面那个)移至B针;

    (3.3)最后我们再把第3.1步中那n-2个盘子从C针全部移回至B针,至此,B针上有n-1个盘子,问题解决。

    经过以上3个步骤,问题进一步弱化了,如3.1所示,需要把n-2个盘子A针(1至n-2号盘)移至C针,我们只需要移动n-2个盘子即可。这个问题熟悉不熟悉?没错,这就是我们要解决的问题(从A->C移动n个盘子),次数减少了两次次数(移动n-2个盘子)的进一步弱化版本么?看到这里相信你已经找到了规律。

    所以,要解决问题3.1我们可以进一步拆分成3个新的子问题,如此反复,就是一个Step1不断递推的过程,直到最后问题被拆分为:需要移动1个盘子从起始针->目标针,此时直接移动即可。这也就是所谓的递推的最后即最终的子问题变成了一个已知问题,递推阶段便结束了。

    递推阶段结束后,便是逐层回归,从已知问题出发,每个n.1问题解决后,顺序解决n.2,n.3,直到回到最开始处,结束回归。比如上述3.1解决后,3.2可直接移动,3.3又可拆分成3个新的子问题,一直拆分到出现已知问题,层层回归解决3.3问题。

    我们是为了解决2.1问题才拆分成3.1,3.2,3.3问题,那么3.1,3.2,3.3问题都解决后,也就是2.1问题被解决了,继续解决2.2问题,2.2问题可直接移动,问题解决。继续解决2.3问题,还是不断递归拆分直到出现已知问题,再不断回归解决问题2.3.

    我们是为了解决我们最初的1问题也就是最初的目标问题才拆分成2.1,2.2,2.3问题的,因此,2.1,2.2,2.3问题都解决后,最初的1问题也就解决了。至此全部结束。

    2.3 C++代码编写

    代码写起来很简单,首先定义一个最基本的操作:移动盘子

    从A移动一个盘子到C,起始针A称为src原盘,终点盘C称为dst目标盘,那么便有:

        //移动src最上面一个盘子到dst针
        void move(char src, char dst)
        {
    	cout << src << "--》" << dst << endl;        //表示将src的一个盘子移动到了dst盘
        }

     接下来我们再定义一个函数:从原盘移动n个盘子到目标盘

    起始针称为src原盘,借助中间盘称为medium中间盘,终点盘称为dst目标盘,那么便有:

        //代表从src->dst(借助medium)移动n个盘子
        void hanoi(int n,char src,char medium,char dest)

    知道以上代表的含义后,我们就可以开始编写代码解决问题了。

    经过2.2章节的分析我们知道,要解决①问题,我们拆分成了3个子问题2.1,2.2,2.3,我们分别看下这三个子问题:

    目标问题:将n个盘子从A针移到C针

    分解步骤1:我们先把n-1个盘子从A针(1至n-1号盘)移至B针(借助C针);

    这个问题写成代码就是:

        //将n-1个盘子从A针(借助C针)移动到B针上
        hanoi(int n-1,A,C,B);

    因为刚开始传入参数时候,赋值的A是src针,B是medium针,C是dst针,所以可以写成:

        //将n-1个盘子从A针(借助C针)移动到B针上
        hanoi(int n-1,src,dst,medium);

     

    分解步骤2:之后将A针中剩下的第n号盘(最下面那个)移至C针;

    这个问题写成代码就是:

        //将A针中剩下的第n号盘(最下面那个)移至C针
        move(A,C);

    因为刚开始传入参数时候,赋值的A是src针,C是dst针,所以可以写成:

        //将A针中剩下的第n号盘(最下面那个)移至C针
        move(src,dst);

     

    分解步骤3:最后我们再把那n-1个盘子从B针全部移至C针(借助A针);

    这个问题写成代码就是:

        //将n-1个盘子从B针(借助A针)移动到C针上
        hanoi(int n-1,B,A,C);

    因为刚开始传入参数时候,赋值的A是src针,B是medium针,C是dst针,所以可以写成:

        //将n-1个盘子从B针(借助A针)移动到C针上
        hanoi(int n-1,medium,src,dst);

    当最终n=1时,我们只需要移动move(src,dst)即可,这也是最终的已知问题。

    因此,完整的代码为:

        void move(char src, char dst)
        {
    	cout << src << "--》" << dst << endl;
        }
    
        void hanoi(int n, char src, char medium, char dst)
        {
    	if (n==1)                                      //n==1代表最终的已知问题
    	{
    	    move(src, dst);
    	}
    	else
    	{
    	    hanoi(n - 1, src, dst, medium);            //子问题2.1,继续调用自身
    	    move(src, dst);                            //子问题2.2
    	    hanoi(n - 1, medium, src, dst);            //子问题2.3,继续调用自身
    	}
        }
        int Exam_3_10()
        {
            int n;
    	cout << "请输入盘子个数:" << endl;
    	cin >> n;
    	hanoi(n, 'A', 'B', 'C');
    	return 0;
        }

    2.4 3层汉诺塔动画演示

    举个简单的例子,假设A上有3个盘子1,2,3盘,也就是3层汉诺塔问题。

    目标问题:我们需要将3个盘子从A针移动到C针(借助B)

    分解问题:

    (2.1)我们可以先把2个盘子从A针(1、2号盘)移至B针;

    (2.2)之后将A针中剩下的第3号盘移至C针;

    (2.3)最后我们再把第2.1步中那2个盘子从B针全部移回至C针,至此,C针上有3个盘子,问题解决。

    步骤如图所示:

    步骤2.1- 先把2个盘子从A移动到B

     

    步骤2.2- 把A上的最后一个盘子移动到C

     

    步骤2.3- 把B上的2个盘子移回C

     

    具体细分到每一步的Gif动画演示如下:

    三层汉诺塔动画演示

     

    展开全文
  • JAVA 遍历文件夹下的所有文件(递归调用和非递归调用) 1、为了方便使用,已经封装成了一个工具FileUtil package com.chen.ftpclient.utils; import java.io.File; import java.util.ArrayList; import java.util....
    JAVA 遍历文件夹下的所有文件(递归调用和非递归调用)

    1、为了方便使用,已经封装成了一个工具FileUtil

    package com.chen.ftpclient.utils;
    
    import java.io.File;
    import java.util.ArrayList;
    import java.util.LinkedList;
    import java.util.List;
    
    /**
     * @author https://blog.csdn.net/chen_2890
     * @description FileUtil
     * @date 2019/6/14 17:29
     */
    public class FileUtil {
    
        /**
         * @description 不使用递归的方法调用
         * @param path 文件夹路径
         * @return java.util.List<java.io.File>
         * @author https://blog.csdn.net/chen_2890
         * @date 2019/6/14 17:34
         * @version V1.0
         */
        public static List<File> traverseFolder1(String path) {
            List<File> fileList = new ArrayList<>();
            int fileNum = 0, folderNum = 0;
            File file = new File(path);
            if (file.exists()) {
                LinkedList<File> list = new LinkedList<File>();
                File[] files = file.listFiles();
                for (File file2 : files) {
                    if (file2.isDirectory()) {
                        System.out.println("文件夹:" + file2.getAbsolutePath());
                        list.add(file2);
                        folderNum++;
                    } else {
                        fileList.add(file2);
                        System.out.println("文件:" + file2.getAbsolutePath());
                        fileNum++;
                    }
                }
                File temp_file;
                while (!list.isEmpty()) {
                    temp_file = list.removeFirst();
                    files = temp_file.listFiles();
                    for (File file2 : files) {
                        if (file2.isDirectory()) {
                            System.out.println("文件夹:" + file2.getAbsolutePath());
                            list.add(file2);
                            folderNum++;
                        } else {
                            fileList.add(file2);
                            System.out.println("文件:" + file2.getAbsolutePath());
                            fileNum++;
                        }
                    }
                }
            } else {
                System.out.println("文件不存在!");
            }
            System.out.println("文件夹共有:" + folderNum + ",文件共有:" + fileNum);
            return fileList;
        }
        /**
         * @description 使用递归的方法调用
         * @param path 文件夹路径
         * @return java.util.List<java.io.File>
         * @author https://blog.csdn.net/chen_2890
         * @date 2019/6/14 17:35
         * @version V1.0
         */
        public static List<File> traverseFolder2(String path) {
            List<File> fileList = new ArrayList<>();
            File file = new File(path);
            if (file.exists()) {
                File[] files = file.listFiles();
                if (null == files || files.length == 0) {
                    System.out.println("文件夹是空的!");
                    return null;
                } else {
                    for (File file2 : files) {
                        if (file2.isDirectory()) {
                            System.out.println("文件夹:" + file2.getAbsolutePath());
                            traverseFolder2(file2.getAbsolutePath());
                        } else {
                            fileList.add(file2);
                            System.out.println("文件:" + file2.getAbsolutePath());
                        }
                    }
                }
            } else {
                System.out.println("文件不存在!");
            }
            return fileList;
        }
    
        /**
         * @description 使用递归的方法调用,并判断文件名是否以.jpg结尾
         * @param path 文件夹路径
         * @return java.util.List<java.io.File>
         * @author https://blog.csdn.net/chen_2890
         * @date 2019/6/14 17:35
         * @version V1.0
         */
        public static List<File> getFileList(String path) {
            List<File> fileList = new ArrayList<>();
            File dir = new File(path);
            // 该文件目录下文件全部放入数组
            File[] files = dir.listFiles();
            if (files != null) {
                for (int i = 0; i < files.length; i++) {
                    String fileName = files[i].getName();
                    // 判断是文件还是文件夹
                    if (files[i].isDirectory()) {
                        // 获取文件绝对路径
                        getFileList(files[i].getAbsolutePath());
                        // 判断文件名是否以.jpg结尾
                    } else if (fileName.endsWith(".jpg")) {
                        String strFileName = files[i].getAbsolutePath();
                        System.out.println("---" + strFileName);
                        fileList.add(files[i]);
                    } else {
                        continue;
                    }
                }
            }
            return fileList;
        }
    }
    
    

    要是还有不太明白的地方请留言,评论必回
    要是对我的文章感兴趣的话,关注一下吧,谢谢!

    上一篇:Linux基本命令

    下一篇:ftp客户端往服务端上传文件

    原来微信打赏还可以备注哦

    在这里插入图片描述

    展开全文
  • javascript 递归调用

    2020-03-01 20:35:26
    递归调用简介:        递归调用是一种特殊的嵌套调用,是某个函数调用自己或者是调用其他函数后再次调用自己的,只要函数之间互相调用能产生循环的则一定是递归调用递归调用...
  • 从JAVA老师讲的JVM的运行机制,使我似乎弄懂了递归调用的原理,C函数的递归调用我也这么理解,编译器分配空间后,一层一层递归,再逐步返回上一级调用,直到满足某个约束条件,函数结束。看来,了解实质的运行机制...
  • vue 组件递归调用

    2018-07-03 11:53:30
    vue组件递归调用,展示树状结构,
  • 如题,在新建线程中递归调用函数,一次结果的返回值由回调函数获取,我想根据线程的状态判断 递归调用是否结束,并获取正确返回值,但是一次执行后线程状态就变成了Stopped了,回调 函数还在继续执行,用...
  • 递归调用思想

    2018-08-17 12:39:30
    * 递归调用 * * 递归调用是一种特殊的嵌套调用,就是程序自身调用自身。 * 递归调用,是某个函数调用自己或者是调用其他函数后再次调用自己的, * 只要函数之间互相调用能产生循环的则一定是递归调用, * 递归...
  • 方法递归调用

    千次阅读 2019-05-29 17:16:26
    递归调用是一种特殊的调用形式,指的是方法自己调用自己的形式。
  • Java中递归调用

    2019-10-29 16:00:39
    递归调用 递归调用分为两种: 直接调用、间接调用 注意:递归调用要有一定的条件限制,保证递归可以停下来。防止出现栈内存溢出。 构造方法禁止递归。 递归打印多级目录 定义一个方法,参数传递File类型的目录,...
  • 关于递归调用

    2017-07-05 10:33:25
    首先先让我们明白一个概念,什么叫递归调用,简单的说——直接或间接调用自身的算法称为递归调用。一个函数能够不断的重复调用自己,来达到计算的目的。递归函数代码精炼,却有着很大的作用,适合作用于复杂、大量的...
  • C语言:函数的递归调用

    千次阅读 多人点赞 2018-07-20 16:14:18
    函数的递归调用:一个函数在它的函数体内,直接或者间接地调用了他本身。 直接递归调用:函数直接调用自身。 间接递归调用:函数间接调用自身。 如下图: 如下图: 防止递归无休止的进...
  • 函数的递归调用

    千次阅读 2018-07-31 18:24:11
    程序中用if语句来控制,只有在某一条件成立时才继续执行递归调用,否则就不再继续,这样,不会出现无终止的递归调用。   2、间接递归 3、程序示例 /* *copyright(c) 2018,HH *All rights reserved. *作 者:...
  • 递归调用的理解

    2019-03-13 15:50:25
    递归四大基本法则 基准情形,跳出递归的条件。 不断推进,每一次调用递归都要有变化,使...设计法则,假设所有的递归调用都能运行。 合成效益法则,切勿在不同的递归调用中做重复性的工作。(例:斐波那契数列) ...
  • 函数的嵌套调用与递归调用 实现C语言求a的n次方
  • Python-函数的递归调用

    2020-07-23 22:53:10
    帅兰一、递归调用解析1、什么是递归调用2、死递归3、递归调用两个阶段4、案例 一、递归调用解析 1、什么是递归调用 即就是说在调用一个函数的过程中,函数内部又调用另一个函数,而函数的递归调用指的是在调用一个...
  • 递归调用机制讲解

    2019-11-25 08:13:19
    递归调用机制 递归的基本思想就是“自己调用自己”,一个使用递归技术的方法将会直接或者间接的调用自己。 接下来讲解一下递归调用,它的内存运行机制。 调用方法时,输入实参是4,调用方法立即开辟一个新栈, ...
  • 递归调用的过程

    2019-11-14 19:20:26
    递归调用的过程 递归的调用是一个不断出栈进栈的过程,将数据在栈中进行保存处理,在使用过后再依次退出栈。 如下为递归调用的演示: 1.int Age(int n) 2.{ 3. int tmp; 4. if(n==1) 5. { 6. return 10; ...
  • 递归调用与二分法 1、递归调用 递归调用:在调用一个函数的过程中,直接或间接地调用了函数本身. 示例: def age(n): if n == 1: return 18 # 结束条件 return age(n-1)+2 # 调用函数本身 print(age(5)) 打印结果...
  • C++ 函数的递归调用

    千次阅读 多人点赞 2017-02-06 00:11:24
    包含递归调用的函数称为递归函数。 比如:int test(int x) { int y; y = test(x); return(2*y); } 以上是一个直接调用的例子,递归调用还包括间接调用,比如:int first(int x) { int b; b =

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 33,925
精华内容 13,570
关键字:

递归调用