给定一个目录,打印出该目录包含的目录或者文件的结构来,文件和其父目录之间通过缩进来表示父子关系。
比如:
0 Test$
--1 src$
----2 TravelDir.java
----2 pms$
--1 bin$
表示Test目录下有两个目录:src和bin,src目录里有一个文件TravelDir.java和一个目录pms。(目录名字后面带$,文件不带)
其实遍历打印目录结构,就是对目录这个”树结构“进行遍历,按照上述结构的话,应该是采用深度优先遍历。
为了完成对特定文件名字的筛选,首先定义一个文件名字过滤接口:(策略模式?O(∩_∩)O)
2 boolean accept(String filename);
3 }
1)采用递归实现
2 * 参数:root:要遍历的文件,
3 *spanToLeft:距离左边的空白或者分隔符数目,
4 *spanChar:空白字符,
5 *filter:根据条件选择文件
6 *
7 */
8 private void travel(File root, int spanToLeft, char spanChar,
9 FileNameFilter filter) {
10 spanToLeft += 4 ;
11 if (root.isFile()) {
12 String name = root.getName();
13 if (filter.accept(name)) {
14 for ( int k = 0 ; k < spanToLeft; k ++ ) {
15 strDir.append(spanChar);
16 }
17 strDir.append(root.getName() + " \r\n " );
18 fileCount ++ ;
19 }
20 } else if (root.isDirectory()) {
21 for ( int k = 0 ; k < spanToLeft; k ++ ) {
22 strDir.append(spanChar);
23 }
24 strDir.append(root.getName() + " $\r\n " );
25 dirCount ++ ;
26 File[] children = root.listFiles();
27 if (children == null )
28 return ;
29 for ( int i = 0 ; i < children.length; i ++ ) {
30 travel(children[i], spanToLeft, spanChar, filter);
31 }
32 }
33 }
34
35 public void travelDir(File root, int spanToLeft, char spanChar,
36 FileNameFilter filter){
37 if (root == null )
38 return ;
39 if ( ! root.exists()) {
40 System.err.println( " file " + root.getName() + " does not exist! " );
41 return ;
42 }
43 travel(root, spanToLeft, spanChar, filter);
44
45 }
2)采用非递归实现(用堆栈)
2 public String filename;
3 public int fileindex;
4
5 public FileDesc(String name, int index) {
6 filename = name;
7 fileindex = index;
8 }
9 }
非递归代码:
2 ArrayList < FileDesc > res = new ArrayList < FileDesc > ();
3 if (root == null )
4 return res;
5 Stack < File > stack = new Stack < File > ();
6 Stack < Integer > stack1 = new Stack < Integer > ();
7 stack.push(root);
8 stack1.add( 0 );
9 while ( ! stack.empty()) {
10 File file = stack.pop();
11 int iii = stack1.pop();
12 if (file.isDirectory()) {
13 FileDesc desc = new FileDesc(file.getName() + " $ " , iii);
14 res.add(desc);
15 dirCount ++ ;
16 File[] children = file.listFiles();
17 if (children == null )
18 continue ;
19 for ( int i = 0 ; i < children.length; i ++ ) {
20 stack.push(children[i]);
21 stack1.push(iii + 1 );
22 }
23 } else if (file.isFile()) {
24 String filename = file.getName();
25 if (filter.accept(filename)) {
26 FileDesc desc = new FileDesc(filename, iii);
27 res.add(desc);
28 fileCount ++ ;
29 }
30 }
31 }
32 return res;
33 }
当初学数据结构的时候,学到树遍历那一章,感觉用递归实现遍历,无论是深度优先还是广度优先(注:转成非递归,深度优先用堆栈,广度优先用队列),代码都比较简单而且容易理解。那时候听说非递归实现很难实现,因此连敢看都没敢看,其实那本书也提供了伪代码。但当时感觉还是不怎么明白,也没怎么仔细看。所以一直以来觉得递归转非递归很难,而且也没怎么实际写过代码。前段时间去参加一个单位的笔试题,里面就有一道题要求用非递归实现二叉树的先序遍历,呵呵,说实话,以前还真没怎么写过,都是用递归。于是在考场时试着写了一下,没想到仔细理了一下思路,很快就写出来了,其实没想象中那么难。最近也在研究了一下算法,感觉还是很有意思的,以前总觉得算法很深奥,其实现在想想,没那么高深,关键不能只是在想,要亲自去试试。