递归算法的注意事项

1、递归的目的是使代码简洁,达到功能实现的目的

2、递归耗性能,占内存高

3、能用迭代的尽量不用递归

4、在使用递归的时候写发也很重要,要尽量减少不必要的再次递归调用

举例1:求25的阶乘

public static void main(String[] args) {
    System.out.println("递归开始时间:"+System.currentTimeMillis());
    System.out.println(getData(25));
    System.out.println("递归结束时间:"+System.currentTimeMillis());
    System.out.println("for循环开始时间:"+System.currentTimeMillis());
    long count = 1;
    for (int i = 1; i <= 25; i++) {
            count *= i;
    }
    System.out.println(count);
    System.out.println("for循环结束时间:"+System.currentTimeMillis());
}

private static long getData(int account){
    if(account==1){
        return 1;
    }else {
        return account*getData(account-1);
    }

}

结果如下:

递归开始时间:1564627877395
7034535277573963776
递归结束时间:1564627877395
for循环开始时间:1564627877395
7034535277573963776
for循环结束时间:1564627877395

对比发现两个时间无差别。

针对3举例如下:

已知数列:1,1,2,3,5,8,13,21,34,..... 打印第50次的总数

public static void main(String[] args) {
    System.out.println("递归开始时间:"+System.currentTimeMillis());
    System.out.println("总数:"+getBit(50));
    System.out.println("递归结束时间:"+System.currentTimeMillis());
    System.out.println("for循环开始时间:"+System.currentTimeMillis());
    System.out.println("总数:"+getBits(50));
    System.out.println("for循环结束时间:"+System.currentTimeMillis());
}

private static long getBits(int month) {
    long s=1;
    long s1=1;
    long s2=1;
    if(month==1 || month==2){
        return 1;
    }else {
        for (int i = 3; i <=month ; i++) {
            s=s1+s2;
            s1=s2;
            s2=s;
        }
        return s;
    }
}

private static long getBit(int month){
    if(month==1 || month==2){
        return 1;
    }else {
        return getBit(month-1)+getBit(month-2);
    }
}

运行后时间消耗对比:

递归开始时间:1564625707390
总数:12586269025
递归结束时间:1564625752422
for循环开始时间:1564625752422
总数:12586269025
for循环结束时间:1564625752422

发现递归消耗的时间跟for循环不在一个级别上,循环0实现,而递归很耗时。


针对4举例如下:

文件夹的删除功能,分析:在删除文件夹时,如果有子文件或子文件夹时,要先删除子文件和子文件夹,才能删除该文件夹。由于文件夹下会有文件夹和文件,在删除文件夹时要对该文件夹做判断。如果存在子文件和子文件夹,子文件可以直接删除,子文件夹要再次判断。如果子文件夹下还存在子文件和子文件夹,就要再次判断子文件夹的子文件夹...。这就会想到递归循环。

递归方法1:

private static boolean deleteDir (File dir) {
        if (dir.isDirectory ()) {//是文件夹
            File[] files = dir.listFiles ();
            for (File file : files) {
                    deleteDir (file);
            }
        }
        dir.delete ();//是文件夹通过上面的递归就已经删空了,最后不管是空文件夹还是文件都删除
        return true;
    }

递归方法2:

private static boolean deleteDir (File dir) {
        if (dir.isDirectory ()) {//是文件夹就列表递归删除
            File[] files = dir.listFiles ();
            for (File file : files) {
                if (file.isDirectory ()) {//是文件的话就直接删除,减少了递归的消耗
                    deleteDir (file);
                } else {
                    file.delete ();
                }
            }
        }
        dir.delete ();
        return true;
    }

同样是删除,方法2比方法1多了一个判断,对性能上即是一个大的提升。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值