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

一,介绍

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

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 }
时间: 2024-10-23 21:03:49

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

(原)neuq oj 1022给定二叉树的前序遍历和后序遍历确定二叉树的个数

题目描述 众所周知,遍历一棵二叉树就是按某条搜索路径巡访其中每个结点,使得每个结点均被访问一次,而且仅被访问一次.最常使用的有三种遍历的方式: 1.前序遍历:若二叉树为空,则空操作:否则先访问根结点,接着前序遍历左子树,最后再前序遍历右子树. 2.中序遍历:若二叉树为空,则空操作:否则先中序遍历左子树,接着访问根结点,最后再前中遍历右子树. 3.后序遍历:若二叉树为空,则空操作:否则先后序遍历左子树,接着后序遍历右子树,最后再访问根结点. 现在的问题是给定前序遍历和后序遍历的顺序,要求出总共有多

先序遍历和后序遍历构建二叉树

递归的方法利用先序遍历和中序遍历构建二叉树,同样也可以利用到中序遍历和后序遍历构建二叉树. //利用先序遍历和中序遍历构建二叉树 TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) { TreeNode *root=NULL; if(preorder.size()==0||inorder.size()==0||preorder.size()!=inorder.size()) return

已知二叉树的前序遍历、中序遍历或者中序遍历、后序遍历求二叉树结构的算法

二叉树中的前序遍历是先访问根结点,再访问左子树,右子树. 中序遍历是先访问左子树,再是根结点,最后是右子树. 后序遍历是先访问左子树,再是右子树,最后是根结点. 算法思路是先根据前序遍历的第一个结点或者后序遍历的最后一个结点,查找对应在中序遍历中的位置,就可以确定左子树包含的元素和右子树包含的元素,最后通过递归来实现就可以了. 二叉树的表示形式为 //二叉树的结构表示为 class TreeNode { int val; TreeNode left; TreeNode right; TreeNo

51nod 1832 先序遍历与后序遍历【二叉树+高精度】

题目链接:51nod 1832 先序遍历与后序遍历 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 对于给定的一个二叉树的先序遍历和后序遍历,输出有多少种满足条件的二叉树.两棵二叉树不同当且仅当对于某个x,x的左儿子编号不同或x的右儿子编号不同. Input 第一行一个正整数n(3<=n<=10000),表示二叉树的节点数,节点从1到n标号. 第二行n个整数a[i](1<=a[i]<=n),表示二叉树的先序遍历. 第三行n个整数b[i](1<

二叉树的遍历规则(前序遍历、后序遍历、中序遍历)

今天看了一些关于平和查找二叉树的问题,顺便也复习了一下二叉树的遍历规则,写一下学习文档. 树的遍历顺序大体分为三种:前序遍历(先根遍历.先序遍历),中序遍历(中根遍历),后序遍历(后根遍历). 如图所示二叉树: 前序遍历:前序遍历可以记为根左右,若二叉树为空,则结束返回. 前序遍历的规则: (1)访问根节点 (2)前序遍历左子树 (3)前序遍历右子树 这里需要注意:在完成第2,3步的时候,也是要按照前序遍历二叉树的规则完成. 前序遍历的输出结果:ABDECF 中序遍历:中序遍历可以记为左根右,也

已知一棵二叉树的中序遍历和后序遍历,求二叉树的先序遍历

[题解整理]二分题 题目类型: 二分查找: 二分答案. 大致解题思路: 查找注意有序和返回值: 浮点数注意精度: 整数注意返回值,建议另外维护一个变量,用于储存可行解. 题目 分类 传送门 WA点 poj 2785 二分查找 题解 lightoj 1088 二分查找 题解 lightoj 1307 二分查找 题解 longlong poj 2456 整数二分答案 题解 poj 3104 整数二分答案 题解 poj 3258 整数二分答案 题解 poj 3273 整数二分答案 题解 lightoj

二叉树重建 - (先序遍历、中序遍历、后序遍历)

对于一棵二叉树T,我们可以递归定义它的先序遍历,中序遍历,后序遍历:  1.先序遍历  ( PreOrder(T) = T的根节点 + PreOrder(T的左子树) + PreOrder(T的右子树) ) 2.中序遍历  ( InOrder(T) = InOrder(T的左子树) + T的根节点 +  InOrder(T的右子树) ) 3.后序遍历  ( PostOrder(T) = PostOrder(T的左子树) + PostOrder(T的右子树)  + T的根节点 ) 其中,加号表

002.深入浅出理解[二叉树的构建、先中后序遍历、树的深度、左右子树互换]

二叉树本来就是递归定义的,如果对递归还不是特别了解,建议看一下<001.深入浅出解释[递归]> 写一个递归函数很简单,只需要记住下面2点: 1.递归中止条件:对于二叉树来说一般是node==null的时候判断到了叶子结点 2.递归函数::描述一个中间过程,然后用代码实现,调用自身的时候传递的参数就是你想要递归的方式. 下面的代码就是一个二叉树的创建.先中后序遍历.树的深度.左右子树的互换的过程 #include <stdio.h> // 定义二叉树的结点 struct treeNo

LintCode(72)中序遍历和后序遍历树构造二叉树

题目 中序遍历和后序遍历树构造二叉树 根据中序遍历和后序遍历树构造二叉树 样例 给出树的中序遍历: [1,2,3] 和后序遍历: [1,3,2] 返回如下的树: 2 /  \ 1    3 分析 递归解决. Python代码 """ Definition of TreeNode: class TreeNode: def __init__(self, val): self.val = val self.left, self.right = None, None "&q