精华内容
下载资源
问答
  • 我们发现中都是一些条件只有满足这些条件了才会进行{}中的动作 那么java中的这些条件是怎么写的呢 这也是我们这节课学习的难点 下面要学习两种类型的运算符 1关系运算符 2逻辑运算符 Java递归调用 汉诺塔 主讲人熊...
  • 按照这个说法,个简单的递归自己推导一下的确可以,但是总是有点绕,推着推着自己把自己陷进去了。递归函数运行时,实际上会进行一个压栈(思考栈的特点,先进后出,后进先出)的过程。个简单的递归排序算法:...

    递归到底是个啥?

    常听见的一句话就是:自己调用自己。

    按照这个说法,写个简单的递归自己推导一下的确可以,但是总是有点绕,推着推着自己把自己陷进去了。

    递归函数运行时,实际上会进行一个压栈(思考栈的特点,先进后出,后进先出)的过程。

    写个简单的递归排序算法:

    public static voidmain(String[] args) {int[] arr={1,3,4,2};

    System.out.println(digui(arr,0,arr.length-1));

    }public static int digui(int[] arr,int L,intR){if(L==R)returnarr[L];int mid=(L+R)/2;int LeftMax=digui(arr,L,mid);int RightMax=digui(arr,mid+1,R);returnMath.max(LeftMax,RightMax);

    }

    当第一次进入digui方法时,在第十行,也就是

    int LeftMax=digui(arr,L,mid);

    1.程序会第一次进入到子方法,也就是调用本身。这时候会往堆栈里面记录此时这个方法的信息,比如L=0,R=3,mid=1等等,并且暂停这个方法的继续运行,先进入到子方法。

    2.程序进入子方法,第二次到第十行代码时,依旧会往堆栈里记录此时的方法信息,L=0,R=1,mid=0等等

    3.程序再次进入子方法,第三次运行到第十行代码时,此时L=0,R=0。所以会返回arr[0],也就是1.因为返回了数值,没有再次调用自己,所以不用再次压栈

    此时的堆栈信息如图

    dd5c3fe24efa94bd0e78e417c52abcdf.png

    4.由于上一步返回了一个1,那么自然就会先回到其父方法,也就是L=0,R=1,mid=0的这个方法。这时候LeftMax就会接受到其子方法的返回的数据,也就是1.

    5.接着运行第十一行代码,继续压栈,然后运行其子方法。自己捋一下,第十一行的子方法返回的是3

    6.接着运行第十二行代码,会比较1和3谁大,然后返回。至此,L=0,R=1,mid=0时的这个方法彻底执行完毕,接着就会执行出栈操作。

    有了堆栈图的辅助,理清递归过程就清晰多了。大家可以自己捋一捋接下来几步的过程。总比以前光凭一个脑袋想好多了。

    递归的时间复杂度怎么算?

    一般情况下,可以用以下公式:

    T(N)=aT(N/b)+O(N^d);

    其中,T是样本,N的样本量。

    b代表这个样本被分为了几部分(上面的算法被分为两部分(L+R)/2,所以b=2),a代表运行了多少次(上面的算法需要调用自己两次,所以a=2)。

    一定要记住,这个a和b,不需要展开所有堆栈里的情况,只需要看最表面上的代码就行,不用想里面的子方法还调用了多少次本身。

    后面接着的O(N^d)代表除了前面那部分主体外,还需要多少时间复杂度,比如前面的aT(N/b)这部分运行完,我还需要O(N^2)的时间复杂度才能最终完成输出,那么d=2。

    那么T(N)=aT(N/b)+O(N^d)到底怎么求出具体结果呢?

    628c2083bff3c3d6d8abf9587e3186c9.png

    上面的算法中,a=2,b=2,d=0

    所以log(b,a)=1.大于d的。所以时间复杂度为O(N)

    展开全文
  • 一、递归是什么? 定义:程序调用自身的... 定义不明白不要紧,先思考以下表达式,要怎么写程序来计算呢?1+2+3....+100=? 很多人第一反应使用for循环来解决: 或者二逼青年使用最简洁而且高效的公式(推荐使用,开销最...

    一、递归是什么?

    定义:程序调用自身的编程技巧称为递归。它分为调用阶段和回退阶段,递归的回退顺序是它调用顺序的逆序。

    递归使用的是选择结构:if/switch。而for,while,do while使用的是循环结构。

    定义不明白不要紧,先思考以下表达式,要怎么写程序来计算呢?

    1+2+3....+100=?

    很多人第一反应使用for循环来解决:

    95aaa4d6ed04a45a728d08dfd89cca17.png

    或者二逼青年使用最简洁而且高效的公式(推荐使用,开销最小,且一步到位):

    0688a07550b92403c63e0acaea8e84fe.png

    而递归代码如下:

    1cf88d3526630e5789f7617ffba67b1c.png

    通过初体验对比,不难发现以下递归有以下几个要点:

    1.优点:使程序结构更清晰,更简洁,更容易让人理解,

    2.缺点:使用递归调用时,如果过多的调用容易造成java.lang.StackOverflowError即栈溢出和程序执行过慢。这是一个潜在Bug和影响程序执行效率问题,需要谨慎使用。对于互联网这种以速度和效率来维护用户量,不得以用递归时,可以把处理的数据放入缓存,或者直接使用迭代等方式来解决。

    3.规律:递归要有出口,不然成了死循环。解出递归的要点在于求出n-1,求出了n-1才能求解出n,这是为什么呢?

    二、递归的执行过程

    前文对于递归的定义中说,递归分为调用阶段和回退阶段,递归的回退顺序是它调用顺序的逆序。为了理解执行过程,这里配合实例讲解。请思考如何写出它的递归代码:

    n!=n*(n-1)*(n-2)...*3*2*1

    这里给出数学表达式:

    b9e8fc6b9a09cbac454350355fa20943.png

    从表达式中可以明显的可以看出:1.递归有出口。2.递归是选择结构。递归代码也不难:

    fa509bbfbee95cbe5d9de22c32190a7f.png

    它的调用顺序是怎么样的呢?

    0aaad860a4e03c09ae0ea0f5fb75f3a2.png

    当你传入5时,方法内会去调用方法factorial(4),然后又调用方法factorial(3)直到factorial(0)=1时开始返回,下面为更详细的图解:

    调用阶段

    14b3238a53e32b3812d33f0d67bdddc2.png

    回退阶段

    d48e4be90639fe5249fa734973185cf0.png

    图中红色箭头为调用阶段,绿色箭头为回退阶段。这就是递归的要点在于求出n-1,求出了n-1才能求解出n,它思想其实和数学中的归纳本质上是相同的。

    三、汉诺塔游戏讲解

    游戏规则:有三根柱子,最左边的一根柱子从下往上按照大小顺序摞着64片圆盘。需要你借助中间的柱子把左边的所有圆盘移动到最右边的柱子上。并且规定,下面圆盘始终要比上面的大,在三根柱子之间一次只能移动一个圆盘。求出最少移动的次数。

    如果要把X柱上得3个圆盘移动到Z柱,步骤如下:

    ①把X柱最上面的小圆盘移动到Z柱。②再把X柱中间大的圆盘移动到Y柱。③把Z柱上最小的圆盘移动到Y柱上。

    这三次操作如图所示:

    441479cf17d16598260e6df9810a5231.png

    再加上步骤④⑤⑥⑦,所以3个圆盘至少需要移动7次。如果移动6个圆盘时:

    c8865857d8adc50e13fcb7e77fdfe34c.png

    所以可以推出,当n个从x柱,经由y柱中转,移动到z柱(解出n层汉诺塔时),有:

    当n=0时,

    不用做任何操作

    当n>0时,

    首先,将n-1个盘子从x借助z移动到y

    然后,将1个盘子从x移动到z

    最后,将在中间y上的n-1个盘子借助x移动到z

    为了解出n层汉诺塔,需要先使用n-1层汉诺塔的解法。

    17662ad2a0fd0062ca9588a3de751781.png

    从推到过程中我们可以发现:解出递归的要点在于求出n-1,求出了n-1才能求解出n。此外,从数学角度也可以归纳出 0,1,3,7,15,63...表达式为:f(n)=2^n - 1。

    现在,我们可以给出代码:

    0247e6377404a77c26835d8cef80fb1a.png

    四、总结和展望

    递归对于解决某些问题非常方便(比如递归读取文件路径),也易于理解。虽然用迭代不是不可以实现,只是同样为了解决某些特性问题,写出迭代的代码花费的时间和难度却比递归高。

    前文提到,递归和数学中的归纳思想本质上是相同的,都是"将复杂的问题简化"。掌握递归思想的核心就在于"把握结构

    展开全文
  • Java入门-方法(定义、调用、重载、递归) 什么是方法? 方法如何被定义? 怎么调用方法? 运用方法的练习题 方法的重载 关于重载的练习题 一、什么是方法? 如果把你的代码比作一个肥宅快乐水工厂,...

    Java入门-方法(定义、调用、重载、递归)

    1. 什么是方法?
    2. 方法如何被定义?
    3. 运用方法的练习题
    4. 怎么调用方法?
    5. 方法的重载
    6. 关于重载的练习题
    7. 递归

    一、什么是方法?

    如果把你写的代码比作一个肥宅快乐水工厂,那么方法就是你工厂中的生产线中的一个行为:制作肥宅快乐水的罐子、灌装快乐水、封盖儿、装饰、投入市场…等中的任何一个环节。

    我们回想一下,肥宅快乐水瓶罐上面的装饰图案是否基本一致?那么这个行为是否就是一种重复性的行为?我们还有必要每来一瓶快乐肥皂水都让装饰这个行为:设计师去设计图样-产品经理审核图样-工程师操纵机器进行涂刷整个走一遍吗?是不是可以直接把图样整合到涂刷机器中去,等我的阔乐运到该区域,就直接涂就行了。

    我的看法是方法就是一种偷懒儿的方式,把重复出现的代码放在方法里面,就可以直接反复调用即可,而不是每次我要实现个什么,又要去写一模一样的一大坨代码。
    使用方法可以增加可读性。

    二、方法如何被定义?

    定义格式:
    public static void 方法名称(){
    方法体
    }

    方法其实就是若干语句的功能集合

    方法的定义里方法还是像一个工厂,还是以我们的快乐肥宅水工厂为例:
    原料:果葡糖浆、白砂糖、水、食品添加剂
    产出物:快乐肥宅水
    参数(原料):进入方法的数据
    返回值(产出物):从方法中出来的数据

    定义方法的完整格式
    修饰符 返回值类型 方法名称(参数类型 参数名称,…,参数类型 参数名称){
    方法体
    return 返回值;
    }

    修饰符:入门阶段,就记住是public static就行
    返回值类型:也就是方法最终产生的数据
    方法名称:方法的名字,规则和变量一样,小驼峰
    参数类型:进入方法的数据是什么类型
    参数名称:进入方法的数据对应的变量名称
    ps: 参数如果有多个,使用逗号进行分隔
    方法体:方法需要做的事情,若干行代码
    return:两个作用,第一停止当前方法,第二将后面的返回值还给调用处
    返回值:方法执行后最终产生的数据结果

    注意
    1.方法应该定义在类当中,并且里面不能嵌套方法,只能平行关系
    2.方法没有先后顺序,而且方法不会自动执行,调用了才会运行
    3.return后面的“返回值”,必须和方法名称前面的返回值类型保持一致
    4.对于void(),可以写return;来结束,但是不能返回值
    5.一个方法当中可以有多个return语句,但是只能保证有且仅有一个被执行,不能同时可能多个执行

    三、运用方法的练习题

    题目1:定义一个两个int类型的数字相加的方法。

    Tips:
    使用方法一定要首先弄清楚三要素,再去着手写,思路清晰了才不会错。
    三要素:
    返回值类型:int
    方法名称:sum
    参数列表:int a, int b

    题目1可参考代码:

    package com.tan.day1.demo2;
    
    public class MethodDefine {
        public static void main(String[] args) {
            System.out.println(add(2,5));
        }
    
        public static int add(int a,int b) {
            int result = a + b;
            return result;
        }
    }
    

    题目2:定义一个方法,用来判断两个数字是否相同

    题目3:求1到100的累加和

    题目4:打印指定次数的HelloWorld

    四、怎么调用方法

    方法的三种调用方式
    1.单独调用:方法名称(参数);

    2.打印调用:System.out.println(方法名称(参数));

    3.赋值调用:数据类型 变量名称= 方法名称(参数);

    e.g:
    int i=方法名称(参数);
    System.out.println(“调用方法后的值为:” + i);

    方法调用的流程
    1.找到方法
    2.传参
    3.执行方法体
    4.带着返回值回到方法的调用处(谁调用我,我就把返回值还给谁)

    有参数的方法和无参数的方法的区别
    方法名后面的括号里面有东西,就是有参数的
    实例:

    package com.tan.day1.demo2;
    
    public class MethonParam {
        public static void main(String[] args) {
            System.out.println("你好哇,我调用的是无参的方法:");
            noParma();
            /*输出结果:
             *
             **
             ***
             ****
             *****
             ******
             *******
             实现了一个打印三角形的功能
             */
            System.out.println("你好哇,我现在调用的是有参的方法哦:");
            //输出结果:我是小谭,我今年3岁了
            System.out.println(haveParma("小谭","3岁"));
    
        }
    
        public static void noParma(){
            for (int i = 1; i <= 7; i++) {
                for (int j = 0; j < i;j++) {
                    System.out.print("*");
                }
                System.out.println();
            }
        }
    
        public static String haveParma(String a,String b){
    
            return ("我是"+ a +",我今年"+ b +"了");
        }
    }
    

    有返回值的方法和无返回值的方法的区别
    求值得用有返回值,因为最后结果需要返回
    执行方法体后,有返回值的方法会将返回值交还给调用处,无返回值的方法会直接结束
    实例:

    package com.tan.day1.demo2;
    
    public class MethodReturn {
        public static void main(String[] args) {
    
            System.out.println("你好哇,我调用的是无返回值的方法:");
            noReturn(1,7);
            System.out.println("你好哇,我现在调用的是有返回值的方法哦:");
            System.out.println(haveReturn("小谭","3岁"));
    
        }
    
        public static void noReturn(int a,int b){
            for (int i = a; i <= b; i++) {
                for (int j = 0; j < i;j++) {
                    System.out.print("*");
                }
                System.out.println();
            }
        }
    
        public static String haveReturn(String a,String b){
            return ("我是"+ a +",我今年"+ b +"了");
        }
    }
    

    五、方法的重载

    重载:多个方法的名称一样,但是参数列表不一样

    注意:

    有关:
    1.参数个数不同
    2.参数类型不同
    3.参数的两个及以上的类型顺序不同
    无关:
    1.与参数名称无关
    2.与方法的返回值类型无关

    六、重载的练习题

    1.判断两个数据是不是相等的
    (参数类型分别为两个byte类型、两个short类型、两个int类型、两个long类型)

    2.判断哪些方法是重载关系:

    public static void open(){ } //是
    public static void open(int a){ } //是
    static void open(int a,int b){ } //和最后一个冲突
    public static void open(double a,int b){ } //是
    public static void open(int a,double b){ } //和第六个冲突
    public void open(int i,double b){ } //和第五个冲突
    public static void OPEN(){ } //不是,不同名字
    public static void open(int i,int j){ } //和第三个冲突

    一个小tips:println()其实就是进行了多种数据类型的重载形式

    七、方法的递归

    递归:
    调用自身

    注意:
    必须要有结束条件,否则会进入死循环,永远无法结束调用。

    展开全文
  • 不是很难,可以自己构造个file对象,然后尝试尝试它的一些方法,方法的名字都很好理解,不多说直接上代码,演示下常用的方法以及怎么配合递归遍历到指定文件夹下的所有文件。 public class Review1 {

    File类、递归

    java.io.File类是文件和目录路径名的抽象表示,主要用于文件和目录的创建、查找和删除等操作。

    递归指当前方法内调用自己的这种现象,一般的循环不建议使用递归,效率低,每一次方法的执行都会开辟一个栈空间,不过在算法里面倒是蛮有用的,递归回溯、排序,是一种以空间换时间的方法。

    不是很难,可以自己写构造个file对象,然后尝试尝试它的一些方法,方法的名字都很好理解,不多说直接上代码,演示下常用的方法以及怎么配合递归遍历到指定文件夹下的所有文件。

    public class Review1 {
        private static final File file = new File("D:\\file\\b");// (window7的分隔符)
        public static void main(String[] args){
            // getAllFile(file);
            // getTxt();
            getAllFile2(file);
        }
    
        public static void getTxt() {    
            File[] files = file.listFiles();// 拿到该路径下的所有文件和目录
            for (File file2 : files) {
                if (file2.getName().endsWith(".txt")) {// 筛选一下
                    System.out.println(file2.getPath()+"  "+file2.length()+"个字节");
                }
            }
        }
    
    	// 开始递归,获取所有该路径下的文件(而不是目录)
        public static void getAllFile(File file) {
            File[] files = file.listFiles();
            for (File file2 : files) {
                if (file2.isDirectory()) {
                    getAllFile(file2);   
                }else if(file2.isFile()){
                    System.out.println(file2.getName());
                }
            }
        }
    
    	// listFiles可以接收一个FileFilter文件过滤器,我们重写唯一的一个accept方法,该
    	// 方法只有返回为true时,相应的file的路径对象才可以被返回。直接用lambda表达式写下
        public static void getAllFile2(File file) {
            File[] files = file.listFiles(pathname->pathname.getName().endsWith(".txt"));
            for (File file2 : files) {
                System.out.println(file2.getName());
            }
        }
    }
    
    
    展开全文
  • JAVA实现树结构List递归遍历

    千次阅读 2020-04-30 00:04:52
    由于之前在树结构遍历的时候都是 copy 的别人的代码,想着把功能完成就行,并没有真正理解如何实现的遍历的,又怎么递归。前几天尝试着自己一个遍历树结构 List,其实很简单,所以能自己动手,决不要 copy。先...
  • 一、递归是什么? 定义:程序调用自身的编程技巧称为递归。它分为调用阶段和回退阶段,递归的回退顺序是它调用顺序的逆序。... 定义不明白不要紧,先思考以下表达式,要怎么写程序来计算呢? 1+2+3....+100=? ...
  • java.io.File 底层是调用与c语言接的接口,所以我们暂时不需要知道底层是怎么实现的,再说了,也看不见,最多就是看见一个接口而已。我们只需要知道java.io.File提供给我们对文件的一些操作就行了。1.文件的创建:...
  • 这次把递归版本重新了一下,着重于图解部分,将递归怎么一步步调用的,怎么一步步返回的详细画了一遍。先来回顾下这道题目吧:将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的...
  • 小的最近在学习java,有一点疑问,请大牛指点。谢谢 子类总会有一个自己的构造函数,在这个构造函数的第一行去隐式或者显式super地调用 父类的构造函数。...我的问题是:Object构造函数的super()是怎么写的呢?
  • java.io.File 底层是调用与c语言接的接口,所以我们暂时不需要知道底层是怎么实现的,再说了,也看不见,最多就是看见一个接口而已。我们只需要知道java.io.File提供给我们对文件的一些操作就行了。 1.文件的创建.....
  • Java 链表的定义与简单实例Java实现链表主要依靠引用传递,引用可以理解为地址,链表的遍历多使用递归,这里我存在一个疑问同一个类的不同对象的的相同方法的方法内调用算不算递归.这里我的是单向链表;package ...
  • 理解递归

    2020-12-31 12:56:31
    那么在java用方法怎么写呢? 运行结果为7; 写方法的时候,f(x)=x+3,把x作为形参变量写进括号里,“=”后面的表达式写进方法体; 最后在main 方法里调用这个方法 f(4);即可求得f(4)的值。 既然我们知道数学里f(x)...
  • 递归写冒泡排序会吗?差点疯掉,说实在的真没怎么用过递归。我跟他说,你让我用电脑试试,我肯定能整出来,结果面试官没给机会。特此纪念一下吧!递归是什么?通俗的讲:在方法内部调用自己(相当于现实中的...
  • 让我们看一个简单的例子,在我们初学Java的时候,老师要求我们怎么去获取十进制整数的二进制表现形式,如:求6的二进制形式,那么一开始我们的代码可能是这样的: public static void toBin(int num){ while(num...
  • 一篇文章彻底学会递归思路解题! 哈希算法详解 计算机网络(TCP/IP协议栈) 计网 IP 知识全家桶,45 张图一套带走 ping命令用得这么6,原理知道不?图解一波! 探究:一个数据包在网络中到底是怎么游走的? 硬不...
  • 这道题本来方法很简单,两个递归调用就解决了,而且还是0ms,可是我想还原完整的函数入口,就重新建树,输出,可是居然不对了,哎呀,怎么搞得,好笨呐/(ㄒoㄒ)/~~ 原本的别人的0ms方法是这样的: public class ...
  • 疯狂JAVA讲义

    2014-10-17 13:35:01
    学生提问:为什么我创建Java对象时从未感觉到java.lang.Object的构造器被调用过? 150 5.7 多态 151 5.7.1 多态性 151 5.7.2 引用变量的强制类型转换 152 5.7.3 instanceof运算符 154 5.8 继承与组合 154 ...
  • java杨辉三角金字塔型

    2020-05-18 19:14:27
    可能有点笨拙,因为没用到方法调用递归,当然这样更容易新手秒懂。 public claa TestYHSJ{ public static void main(String[] args){ int[][] array=new int[10][10];//array作为一个普通数组必须要先定义长度,...
  • java面试宝典2012

    2012-12-16 20:43:41
    给一个 Bean 的 message 属性, 字符串类型, 注入值为 "Hello" 的 XML 配置文件该怎么写? 137 19、Jdo是什么? 137 20、什么是spring的IOC AOP 137 21、STRUTS的工作流程! 137 22、spring 与EJB的区别!! 137 八. ...
  • 当时真是百思不得姐啊,悲催,心想我只存入一个小小对象,怎么会报着这错误,多次查看代码更是觉得无误,后经高人指点,原来是陷入了方法的递归死循环(自己调用自己),因为我在basedao的时候了一个save方法,...
  • JAVA面试宝典2010

    2011-12-20 16:13:24
    给一个 Bean 的 message 属性, 字符串类型, 注入值为 "Hello" 的 XML 配置文件该怎么写? 125 19、Jdo是什么? 125 20、什么是spring的IOC AOP 126 21、STRUTS的工作流程! 126 22、spring 与EJB的区别!! 126 八. ...
  • 首先我们看下这个功能实现的...第二:根据数据格式分析各级的区别:顶级与二级的区别,二级与三级的区别(这些区别就是在代码时候的条件约束)第三:子列表包含子列表,这里使用递归调用。即将根据本身的id作为父类...
  • Java面试宝典-经典

    2015-03-28 21:44:36
    给一个 Bean 的 message 属性, 字符串类型, 注入值为 "Hello" 的 XML 配置文件该怎么写? 125 19、Jdo是什么? 125 20、什么是spring的IOC AOP 126 21、STRUTS的工作流程! 126 22、spring 与EJB的区别!! 126 八. ...
  • java 面试题 总结

    2009-09-16 08:45:34
    它是基于Java的远程方法调用(RMI)技术的,所以EJB可以被远程访问(跨进程、跨计算机)。但EJB必须被布署在诸如Webspere、WebLogic这样的容器中,EJB客户从不直接访问真正的EJB组件,而是通过其容器访问。EJB容器是...
  • 最新Java面试宝典pdf版

    热门讨论 2011-08-31 11:29:22
    给一个 Bean 的 message 属性, 字符串类型, 注入值为 "Hello" 的 XML 配置文件该怎么写? 125 19、Jdo是什么? 125 20、什么是spring的IOC AOP 126 21、STRUTS的工作流程! 126 22、spring 与EJB的区别!! 126 八. ...

空空如也

空空如也

1 2 3 4 5 ... 7
收藏数 135
精华内容 54
关键字:

java递归调用怎么写

java 订阅