zoukankan      html  css  js  c++  java
  • 二叉树的先序遍历和后序遍历的应用--输出文件和统计目录大小

    一,介绍

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

    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 }
  • 相关阅读:
    ubuntu16.04设置开机自启服务
    Flask架构管理及特点(重要)
    Django开发框架知识点
    Django进行数据迁移时,报错:(1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(6) NOT NULL)' at line 1")
    Java 网络编程(二) 两类传输协议:TCP UDP
    Java 网络编程(一) 网络基础知识
    .NET开源项目
    手写ArrayList、LinkedList
    命令查看java的class字节码文件
    dubbo总结
  • 原文地址:https://www.cnblogs.com/hapjin/p/5396877.html
Copyright © 2011-2022 走看看