递归-
递归(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")); } }
运行结果如下:

浙公网安备 33010602011771号