→阿童沐

財富==支撐一個人生存多長時間的能力!

导航

递归-

递归(Recursion):所谓递归就是方法自己调用自己,对于递归来说,一定有一个出口条件,让递归结束,只有这样才能保证不出现死循环。    八十八

1、经典例题:计算阶乘

package cn.edu.bupt.algorithm;

public class Recursion
{
    /**
     * 通过迭代方式计算阶乘
     * @param num
     * @return
     */
    private static int compute(int num)
    {
        int result = 1;
        for (int i = num; i>0; i--)
        {
            result *= i;
        }
        return result;
    }
    
    /**
     * 通过递归方式计算阶乘
     * @param num
     * @return
     */
    private static int compute1(int num)
    {
        // 考虑递归的出口条件的指定
        if (1 == num)
        {
            return num;
        }
        else
        {
            return num * compute1(num - 1);
        }
    }
    
    public static void main(String[] args)
    {
        System.out.println(Recursion.compute1(5));
    }
}

 


 

2、斐波那契数列

package cn.edu.bupt.algorithm;

public class Fibonacci
{
    private static int compute(int n)
    {
        // 首先确定递归的出口条件
        if (1 == n || 2 == n)
        {
            return 1;
        }
        else
        {
            return compute(n - 1) + compute(n - 2);
        }
    }

    public static void main(String[] args)
    {
        System.out.println(Fibonacci.compute(5));
    }
}

 

3、级联删除目录中的所有内容,因为File#delete()函数是不能删除非空目录的,一定只能将目录中的所有内容清空才能删除当前目录(详见JDK)。

八十八2-01:20

第一种方式:

 

package cn.edu.bupt.io;

import java.io.File;

public class FileDeleteTest
{
    public static void main(String[] args)
    {
        File f = new File("E:\\abc");
        FileDeleteTest.deleteDirectory(f);
        
    }
    
    /**
     * 级联删除目录中的每一个文件,这样只能使用递归实现,因为你不知道目录的层数
     * @param dir
     */
    private static void deleteDirectory(File dir)
    {
        File[] dirs = dir.listFiles();
        
        if (null != dirs)
        {
            for (File f : dirs)
            {
                // 递归函数的出口条件
                if (f.isFile())
                {
                    System.out.println("deleting:" + f.getName());
                    f.delete();
                }
                else
                {
                    // 进行递归
                    FileDeleteTest.deleteDirectory(f);
                }
            }
        }
        // 当其子目录全部删除完成后,删除当前目录
        System.out.println("deleting:" + dir.getName());
        dir.delete();
    }
}

 

 

第二种方式:

package cn.edu.bupt.io;

import java.io.File;

public class FileDeleteTest
{
    public static void main(String[] args)
    {
        File f = new File("E:\\abc");
        FileDeleteTest.deleteDirectory(f);
        
    }
    
    /**
     * 第二种递归删除目录方式
     * @param f    传入的目录或文件的File类型
     */
    private static void deleteAll(File f)
    {
        // 递归的出口条件:当当前File是一个文件类型或是空目录情况,测递归返回
        if (f.isFile() || 0 == f.list().length)
        {
            f.delete();
        }
        // 开始递归
        else
        {
            File[] subFiles = f.listFiles();
            for (File file : subFiles)
            {
                deleteAll(file);
            }
        }
    }
}

  递归必须有一个方法,然后这个方法才能自己调用自己。

 4、列举目标目录中的树状结构(目录在上,文件在下):

package cn.edu.bupt.io;

import java.io.File;
import java.util.Stack;

public class FileTest2
{
    public static void main(String[] args)
    {   
        File file2 = new File("E:/httpcomponents-client-4.1.3");
        FileTest2.listFiles(file2);
    }
    
    private static void listFiles(File directory)
    {
        // 这两个栈的作用是用于将文件类型File和目录类型File进行区分,使得在后边先输出目录类型File,然后在输出文件类型File
        Stack<File> fileStack = new Stack<File>();    // 临时存放文件类型File对象的栈
        Stack<File> dirStack = new Stack<File>();    // 临时存放目录类型File对象的栈
        
        for (File f : directory.listFiles())
        {
            if (f.isFile())
            {
                fileStack.push(f);
            }
            else
            {
                dirStack.push(f);
            }
        }
        
        // 先输出目录类型File
        while (!dirStack.empty())
        {
            File subDir = dirStack.pop();
            System.out.println(space.toString() + subDir.getName());
            space.append("|   ");
            FileTest2.listFiles(subDir);
            space.replace(space.length() - 4, space.length(), "");
        }
        // 再输出文件类型File
        while (!fileStack.empty())
        {
            System.out.println(space.toString() + fileStack.pop().getName());
        }
    }
    
    /**
     * 用于产生缩进格式的分隔符
     */
    private static StringBuilder space = new StringBuilder("");

}

 其实这种方法是在太笨,空间复杂度是O(2n), 完全可以仅仅针对一个File数组对其进行排序即可,具体排序规则可以在Comparator<File>接口中指定:

package cn.edu.bupt.io;

import java.io.File;
import java.util.Arrays;
import java.util.Comparator;

public class FileList
{
    public static void fileList(File file)
    {
        if (file.isFile() || 0 == file.list().length)        // 当file类型为空目录或是单独文件的时候,递归出口
        {
            return;
        }
        else
        {
            File[] files = file.listFiles();
            FileList.sortFilesAndDirs(files);        // 对目录和文件进行归类排序
            
            sb.append("|   ");                        // 用于输出格式
            for (File f : files)
            {
                System.out.println(sb.toString() + f.getName());
                FileList.fileList(f);
            }
            sb.replace(sb.length() - 4, sb.length(), "");    // 取消刚才的输出格式
        }
    }
    
    /**
     * 对目标files数组进行目录和文件的归类排序,通过Arrays.sort(T[], Comparator<T>);方法即可实现
     * @param files
     */
    private static void sortFilesAndDirs(File[] files)
    {
        Arrays.sort(files, new Comparator<File>()
        {
            @Override
            public int compare(File o1, File o2)
            {
                if (o1.isFile() && o2.isFile() || o1.isDirectory() && o2.isDirectory())
                {
                    return 0;
                }
                else if (o1.isDirectory() && o2.isFile())
                {
                    return -1;
                }
                else
                {
                    return 1;
                }
            }
        });
    }
    
    private static StringBuilder sb = new StringBuilder();
    
    /**
     * for test
     * @param args
     */
    public static void main(String[] args)
    {
        FileList.fileList(new File("E:" + File.separator + "httpcomponents-client-4.1.3"));
    }
}

 

运行结果如下:

posted on 2012-05-21 21:32  阿童沐  阅读(218)  评论(0)    收藏  举报