二叉树的先序遍历和后序遍历的应用--输出文件和统计目录大小

一,介绍

本文主要二叉树的两种基本的典型应用:

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         else
21             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         else
24         {
25             File[] files = f.listFiles();
26             for (File file : files) {
27                 size += totalSize(file);
28             }
29         }
30         return size;
31     }
32     
33     /**recursive error
34     private long totalSize(File f, long size){
35         if(f.isFile())
36         {
37             size += f.length();
38         }
39         else
40         {
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         else
56             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 }

 

posted @ 2016-04-15 20:51  大熊猫同学  阅读(2700)  评论(0编辑  收藏  举报