• 递归算法学习心得与体会


    (1)递归关系的描述第n项Un和它之前的若干项(可以是一项,也可以是多项)有一种只与n有关的的关系,这种关系便叫做递归关系了.

    总结:其实当U(n)与它之前的若干项的递归关系中的某种都可以用递推来实现.

    (2)第二点要说的就是递归出口了,递归出口就是能使,被调递归函数返回的出口.
    1.初始化,递归的初始化最容易了,可以随意地写...只要你认为这个出口不但合理,而且能使程序的性能更好就可以了.比如:在计算n!的实例中,我们可以在n==1 处返回return 1;也可以在n==3 return 6;返回.总之合理即可.

    2.关键:一定要全,出口一定要全,比如计算上台阶方法数的实例中,我们的出口有两种情况哦:n==1 return1; n==2 return 2.不要遗漏最好不过了.计算小小的几个数,把出口考虑完,不要死递归.

    3.出口的特性:带返回值,不带返回值.这里想说的是,我们的在出口可做的事情很多(可以是程序必要的,也可以非必要的,你认为要意思,而且你乐此不彼就ok了).

    (3)第三点想说的就是,递归的一个伤痛,栈的溢出:这个不是我们能避免的,所以才有递归转非递归.但我们可以根据递归的深度h来判断某个递归函数有没有可能发生栈溢出错误.因为有些递归函数是不可能产生栈溢出的,这种情况就是递归函数实现回溯功能的经典例子了,比如:四方定理的实例就是这样了.

    /*
    * 兔子问题(斐波那契数列)
    * 有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问第十个月的兔子对数为多少?
    *
    * 一个月:1对
    * 二个月:1对
    * 三个月:2对
    * 四个月:3对
    * 五个月:5对
    * 六个月:8对
    *
    * 规律:从第三个月开始的兔子对数=前两个月的兔子对数之和
    * 出口:当月份是1或者是2的时候,返回兔子对数是1
    */

    public class DiGuiTest {
        public static void main(String[] args) {
            System.out.println(getNumber(10));//55
        }
        
        /**
         * 获取对应月份的兔子对数
         * @return
         */
        public static int getNumber(int month){
            //出口:当月份是1或者是2的时候,返回兔子对数是1
            if(1==month||2==month){
                return 1;
            }else{
                //规律:从第三个月开始的兔子对数=前两个月的兔子对数之和
                return getNumber(month-1)+getNumber(month-2);
            }
        }
    }

    /*
    * 小猴子第一天摘下若干桃子,当即吃掉一半,又多吃一个.第二天早上又将剩下的桃子吃一半,又多吃一个.
    以后每天早上吃前一天剩下的一半另一个.到第10天早上猴子想再吃时发现,只剩下一个桃子了.问第一天猴子共摘多少个桃子?

    出口:当天数是10的时候,返回1
    规律:当天的桃子数=(后一天桃子数+1)*2;
    */

    public class DiGuiTest2 {
        public static void main(String[] args) {
            System.out.println(getNumber(1));//1534
        }
        
        /**
         * 返回对应天数的桃子数
         * @param day
         * @return
         */
        public static int getNumber(int day){
            //出口:当天数是10的时候,返回1
            if(10==day){
                return 1;
            }else{
                //规律:当天的桃子数=(后一天桃子数+1)*2;
                return (getNumber(day+1)+1)*2;
            }
        }
    }

    /*
    * 递归遍历目录下指定后缀名结尾的文件名称
    *
    * 1.将指定的目录封装成File对象
    * 2.调用搜索指定后缀名结尾名称的方法
    * 3.在方法内部进行判断,如果当前的文件是一个标准文件
    * 出口:就判断是否是以指定后缀名结尾,如果是就输出
    * 4.规律:如果当前文件是一个文件夹,那么就获取该文件夹底下所有的子文件,然后再调用该方法进行搜索
    */

    public class DiGuiTest3 {
        public static void main(String[] args) {
            //1.将指定的目录封装成File对象
            File srcFile = new File("D:/");
            //2.调用搜索指定后缀名结尾名称的方法
            search(srcFile,".jpg");
        }
    
        private static void search(File srcFile, String suffix) {
            //3.在方法内部进行判断,如果当前的文件是一个标准文件
            if(srcFile.isFile()&&srcFile.getName().endsWith(suffix)){
                //出口:就判断是否是以指定后缀名结尾,如果是就输出
                System.out.println(srcFile);
            }else if(srcFile.isDirectory()){
                //4.规律:如果当前文件是一个文件夹,那么就获取该文件夹底下所有的子文件,然后再调用该方法进行搜索
                File[] files = srcFile.listFiles();
                for (File f : files) {
                    search(f,suffix);
                }
            }
        }
    }

    /*
    * 递归删除一个带内容的文件夹
    *
    * 1.将要删除的文件夹封装成File对象
    * 2.调用删除文件夹的方法
    * 3.出口:在方法内部判断当前的文件如果是一个标准文件,就直接删除
    * 4.规律:当前的文件对象如果是一个文件夹,那么获取所有的子文件对象,将所有的子文件都删除之后;那么当前的文件夹就变成了一个空文件夹了,然后再进行删除
    */

    public class DiGuiTest4 {
        public static void main(String[] args) {
            //1.将要删除的文件夹封装成File对象
            File srcFile = new File("D:/aa");
            
            //2.调用删除文件夹的方法
            delete(srcFile);
        }
    
        private static void delete(File srcFile) {
            //3.出口:在方法内部判断当前的文件如果是一个标准文件,就直接删除
            if(srcFile.isFile()){
                srcFile.delete();
            }else{
                //4.规律:当前的文件对象如果是一个文件夹,那么获取所有的子文件对象,将所有的子文件都删除之后;
                File[] files = srcFile.listFiles();
                for (File f : files) {
                    delete(f);
                }
                
                //那么当前的文件夹就变成了一个空文件夹了,然后再进行删除
                srcFile.delete();
            }
        }
    }

    总结:最后我总结了,所有的递归函数的结构都是两部分:出口和递归关系.出口一般放在函数前面,而与它之前若干项的关系处理放在后面.

  • 相关阅读:
    基于ObjectCache的应用
    数学趣题——验证角谷猜想
    数学趣题——递归法寻找最小值
    数学趣题——寻找同构数
    数学趣题——表示成两个数的平方和
    数学趣题——马克思手稿中的数学题
    数学趣题——具有特殊性质的数
    数学趣题——验证四方定理
    数学趣题——连续整数固定和问题
    数学趣题——验证尼克彻斯定理
  • 原文地址:https://www.cnblogs.com/ll1994/p/8290195.html
Copyright © 2020-2023  润新知