一,介绍
本文主要二叉树的两种基本的典型应用:
1) 输出某个文件夹下所有文件名称(可以有子文件夹)---用先序遍历实现
2) 统计某个文件夹的大小(该文件夹下所有文件的大小--用后序遍历实现
二,实现分析
对于问题 1),输出文件名称的过程如下:
如果是文件夹,先输出文件夹名,然后再依次输出该文件夹下的所有文件(包括子文件夹),如果有子文件夹,则再进入该子文件夹,输出该子文件夹下的所有文件名。这是一个典型的先序遍历过程。
对于问题2),统计文件夹的大小过程如下:
若要知道某文件夹的大小,必须先知道该文件夹下所有文件的大小,如果有子文件夹,若要知道该子文件夹大小,必须先知道子文件夹所有文件的大小。
这是一个典型的后序遍历过程。
三,代码实现
输出文件名称:
1 public void list(File f){ 2 list(f, 0); 3 } 4 public void list(File f, int depth){ 5 printName(f, depth); 6 if(f.isDirectory()){ 7 File[] files = f.listFiles(); 8 for (File file : files) { 9 list(file, depth + 1);10 }11 }12 }13 14 private void printName(File f, int depth){15 String name = f.getName();16 for(int i = 0; i < depth; i++)17 System.out.print(" ");18 if(f.isDirectory())19 System.out.println("Dir:" + name);20 else21 System.out.println(f.getName() + ":" + f.length()/1024 + "KB");22 }
统计文件夹大小程序如下:
1 private long totalSize(File f){ 2 long size = 0; 3 if(f.isFile()) 4 { 5 size = f.length(); 6 } 7 else 8 { 9 File[] files = f.listFiles();10 for (File file : files) {11 size += totalSize(file);12 }13 }14 return size;15 }
分析:第14行的 return size; 最终返回的是最外层递归(第一层递归时的size),的查找最大/最小节点方法最终返回的是最里层的递归 形成对比。
其实,因为统计 文件夹A 的大小,需要先算出子文件夹大小,最终各个子文件夹大小之和就是 该文件夹的大小。而递归程序,就是从 文件夹A 开始调用的,遇到子文件夹则递归调用,因此应当返回最外层递归的值。
一个错误的递归版本:
1 private long totalSize(File f, long size){ 2 if(f.isFile()) 3 { 4 size += f.length(); 5 } 6 else 7 { 8 File[] files = f.listFiles(); 9 for (File file : files) {10 size += totalSize(file, size);11 }12 }13 return size;14 }
错误的原因如下:
上层目录中文件的大小被重复地统计了。
设统计A目录大小。A目录中包含了一个子目录B,同时包含了c,d,e三个文件。B目录下有 f,g两个文件。
A目录结构如下(大写字母表示目录,小写字母表示文件):
A{B{f,g},c,d,e}
错误的递归方法,在计算B目录的大小时,会把A目录中的c,d,e三个文件的大小也统计进去!!!
整个完整程序如下:
1 import java.io.File; 2 3 public class FileList { 4 public void list(File f){ 5 list(f, 0); 6 } 7 public void list(File f, int depth){ 8 printName(f, depth); 9 if(f.isDirectory()){10 File[] files = f.listFiles();11 for (File file : files) {12 list(file, depth + 1);13 }14 }15 }16 17 private long totalSize(File f){18 long size = 0;19 if(f.isFile())20 {21 size = f.length();22 }23 else24 {25 File[] files = f.listFiles();26 for (File file : files) {27 size += totalSize(file);28 }29 }30 return size;31 }32 33 /**recursive error34 private long totalSize(File f, long size){35 if(f.isFile())36 {37 size += f.length();38 }39 else40 {41 File[] files = f.listFiles();42 for (File file : files) {43 size += totalSize(file, size);44 }45 }46 return size;47 }48 */49 private void printName(File f, int depth){50 String name = f.getName();51 for(int i = 0; i < depth; i++)52 System.out.print(" ");53 if(f.isDirectory())54 System.out.println("Dir:" + name);55 else56 System.out.println(f.getName() + ":" + f.length()/1024 + "KB");57 }58 59 public static void main(String[] args) {60 FileList flist = new FileList();61 File f = new File("F:\\学位论文");62 flist.list(f);63 64 long size = flist.totalSize(f);65 System.out.println(size/1024/1024 + "MB");66 }67 }