一棵樹是一些節點的集合。這個集合能夠是空集;若不是空集,則樹由稱做根(root)的節點r以及0個或多個非空的(子)樹T1,T2,...Tk組成,這些子樹中每一棵的跟都被來自跟r的一條又向邊所連結。每一顆子樹的跟叫作跟r的兒子,而r是每一棵子樹根的父親。算法
將每個節點的全部兒子都放在樹節點的鏈表中。一個節點內部出了節點自己數據外還有兩個引用,分別指向firstChild(第一個兒子)、和nextsibling(下一個兄弟)測試
樹的應用有不少,比較流行和常見的就是文件目錄結構。以下根目錄/usr,/usr又有三個兒子mark、alex、bill,他們本身也是目錄。spa
遍歷一個目錄咱們須要經過遞歸的方式進行,在遍歷時咱們經過tab符將目錄層級分開code
public static void main(String[] args) { File file = new File("E:\\test"); listAll(file, 0);//爲了根目錄不進行縮進,深度設爲0開始 } //輸出文件file目錄結構 public static void listAll(File file, int depth) { //輸出tab縮進 for (int i = 0; i < depth; i++) { System.out.print("\t"); } //輸出文件名並換行 System.out.println(file.getName()); //判斷是否文件夾,若是是進入下一級目錄 if (file.isDirectory()) { depth = depth + 1; for (File f : file.listFiles()) { listAll(f, depth); } } }
輸出結果:blog
test name code coding.txt user clear sean sean文件.txt 測試文件.txt
算法邏輯很簡單,獲取到的文件若是是一個目錄,那麼以遞歸的方式一個一個地處理它全部的兒子。這些兒子均處在下一層的深度上。這種先處理節點,再處理它全部兒子的遍歷方式叫作先序遍歷。遞歸
後序遍歷一個節點的處理工做是在它全部兒子節點計算後進行的。以下代碼示例一樣以上面目錄結構爲例,計算根文件夾大小,根文件夾大小等於他全部子文件或文件夾大小相加,以此類推。get
public static void main(String[] args) { File file = new File("E:\\test"); listAllSize(file, 0); } public static long listAllSize(File file, int depth) { long totalSize = 0L; if (file.isDirectory()) { int d = depth + 1; for (File f : file.listFiles()) { totalSize += listAllSize(f, d); } } else { totalSize = file.length(); } // 輸出tab縮進 for (int i = 0; i < depth; i++) { System.out.print("\t"); } // 輸出文件名並換行 System.out.println(file.getName() + "(" + totalSize + ")"); return totalSize; }
輸出結果:先計算子文件大小,再由全部子文件大小相加獲得父文件大小。test
coding.txt(19720) code(19720) name(19720) clear(0) sean文件.txt(108460) sean(108460) user(108460) 測試文件.txt(37) test(128217)