当前位置 博文首页 > 文章内容

    Java中的什么场景使用递归,如何使用递归

    作者:shunshunshun18 栏目:未分类 时间:2021-09-03 14:45:07

    本站于2023年9月4日。收到“大连君*****咨询有限公司”通知
    说我们IIS7站长博客,有一篇博文用了他们的图片。
    要求我们给他们一张图片6000元。要不然法院告我们

    为避免不必要的麻烦,IIS7站长博客,全站内容图片下架、并积极应诉
    博文内容全部不再显示,请需要相关资讯的站长朋友到必应搜索。谢谢!

    另祝:版权碰瓷诈骗团伙,早日弃暗投明。

    相关新闻:借版权之名、行诈骗之实,周某因犯诈骗罪被判处有期徒刑十一年六个月

    叹!百花齐放的时代,渐行渐远!



    什么是递归?

    程序调用自身的编程技巧叫做递归。

    递归有什么优点?

    递归算法:代码简洁、清晰,并且容易验证正确性。在一定的程度上还能帮我们减少很多重复代码。

    迭代和递归的区别

    迭代是逐渐逼近,用新值覆盖旧值,直到满足条件后结束,不保存中间值,空间利用率高。

    递归是将一个问题分解为若干相对小一点的问题,遇到递归出口再原路返回,因此必须保存相关的中间值,这些中间值压入栈保存,问题规模较大时会占用大量内存。

    递归的三个条件

    • 边界条件
    • 递归前进段
    • 递归返回段

    当边界条件不满足时,递归前进;当边界条件满足时,递归返回。

    什么场景下适合使用递归

    场景一

    项目当中菜单很多都是配置的,并且菜单有时候都是分好几级的,当我给他配置最下级的时候,那么我还得把他的上级保存起来才能用,但是我们又不确定他有几个上级,这个时候可以采用递归调用。

    public void packageParent(Set<String> parentIdSet) {
     Set<String> parentIdSet1 = new HashSet<>();
     for (String parentId : parentIdSet) {
      MenuOrg menuOrg = new MenuOrg();
      Menu menu = menuRepository.findOne(parentId);
      if (menu == null) {
       continue;
      }
      menuOrg.setMenuId(menu.getMenuId());
      menuOrg.setProType(menu.getProType());
      menuOrgRepository.save(menuOrg);
      if (menu.getParentId() != null) {
       parentIdSet1.add(menu.getParentId());
      }
     }
     //判断parentIdSet1是否为空
     if(!CommonUtils.isCollectionBlankOrEmpty(parentIdSet1)) {
      packageParent(parentIdSet1);
     }
    }

    场景二

    计算5的阶乘

    public class Test {
     public static void main(String[] args) {
      System.out.println(f(5));  
     } 
     public static int f(int n) {  
      if (1 == n)   
                return 1;  
            else  
                return n * f(n-1);  
        }  
    }

    此题中,按照递归的三个条件来分析:

    (1)边界条件:阶乘,乘到最后一个数,即1的时候,返回1,程序执行到底;

    (2)递归前进段:当前的参数不等于1的时候,继续调用自身;

    (3)递归返回段:从最大的数开始乘,如果当前参数是5,那么就是54,即5(5-1),即n*(n-1)

    总结

    递归中一定有迭代,但是迭代中不一定有递归,大部分可以相互转换。

    能用迭代的不用递归,递归调用函数,计算有重复,浪费空间,并且递归太深容易造成堆栈的溢出。

    Java 递归算法

    一、概述

    Java递归:简单说就是函数自身直接或间接调用函数的本身。

    二、应用场景

    若:一个功能在被重复使用,并每次使用时,参与运算的结果和上一次调用有关,这时就可以使用递归来解决这个问题。

    使用要点:

    1,递归一定明确条件。否则容易栈溢出。

    2,注意一下递归的次数。

    三、示例

    最简单的递归演示

    public class recursionDemo {  
        public static void main(String[] args) {
            show();
        }
        private static void show() {
            method();
        }
        private static void method() {
            show();
        } 
    }

    四、实际示例

    我们都知道 6的二进制是110,那么程序是怎么执行的呢?

    代码示例:

     public static void main(String[] args) {
            toBin(6);
        } 
        private static void toBin(int num) {
            if (num>0){
                //取余
                System.out.println(num%2);
                toBin(num/2);
            }
        }

    运行过程:

    递归演示二:计算1-5,求和

    public static void main(String[] args) {
            //1-5求和
            int sum = getSum(5);
            System.out.println(sum);
        } 
        private static int getSum(int num) {
            int x=9;
            if (num==1){
                return 1;
            } 
            return  num+getSum(num-1);
        }

    程序运行图:

    五、递归的缺点

    在使用递归时,一定要考虑递归的次数,负责很容易造成虚拟机 “栈溢出”。

    仍然使用上面的求和代码,只是这次将求和基数变为 90000000,看看结果如何

    public static void main(String[] args) {
            //1-90000000求和
            int sum = getSum(90000000);
            System.out.println(sum);
        }
     
        private static int getSum(int num) {
            int x=9;
            if (num==1){
                return 1;
            } 
            return  num+getSum(num-1);
        }

    果然就造成了虚拟机栈溢出。

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持IIS7站长之家博文。