二叉樹的先序遍歷和后序遍歷的應用--輸出文件和統計目錄大小


一,介紹

本文主要二叉樹的兩種基本的典型應用:

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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM