使用非递归的算法来遍历树结构

编写代码对树的遍历在开发种是很常见的,DOM,文件夹等其数据结构其实就是一棵树(Tree),一般都是通过递归的方式来进行遍历(叫”递归深度优先算法”), 但是如果树的层次很多,会使程序出现堆栈溢出(Stack Over)异常;其实非递归遍历树的算法也是很简单的,除了可以规避堆栈溢出风险外还有速度快的优点!
在这里我以遍历目录为例,演示遍历树的2种方法:非递归广度优先 算法(就是先找出同层的所有节点), 非递归深度优先 算法(就是先找出一个节点下的所有子子孙孙节点)

废话少数,直接上源码:

package wjw.demo;

import java.io.*;

import java.util.*;

/**
 * @author wjw465150@gmail.com
 *
 */
public class Main {
 
    public Main() {
    }
 
    /**
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        if (args.length != 1) {
            System.out.println("Usage: Main [path name]");
            System.exit(0);
        }
 
        Main main = new Main();
 
        System.out.println("1.非递归广度优先");
        main.doIterator1(args[0]);
 
        System.out.println("--------------------------------------------------------------------");
 
        System.out.println("1.非递归深度优先");
        main.doIterator2(args[0]);
    }
 
    //非递归广度优先算法
    private void doIterator1(String rootPath) throws Exception {
        File rootFile = new File(rootPath);
        int level = 1;
        System.out.println(rootFile.getCanonicalFile());
 
        LinkedList<WrapperFileNodeLevel> list = new LinkedList<WrapperFileNodeLevel>();
        File[] childs = rootFile.listFiles();
        if (childs != null) {
            for (File child : childs) { // 1.先添加第1层的子节点到迭代列表里
                list.add(new WrapperFileNodeLevel(child, level + 1));
            }
        }
 
        WrapperFileNodeLevel wrap;
        while (!list.isEmpty()) { // 2. 开始迭代
            wrap = list.removeFirst(); // 移除并返回此列表的第一个元素
            if (wrap.file.isDirectory()) {
                System.out.println(convertLevel2Str(wrap.level) + "[" + wrap.file.getCanonicalPath() + "]");
            } else {
                System.out.println(convertLevel2Str(wrap.level) + wrap.file.getCanonicalPath());
            }
 
            childs = wrap.file.listFiles();
            if (childs != null) {
                for (File child : childs) {
                    list.add(new WrapperFileNodeLevel(child, wrap.level + 1)); // 3.有子节点则加入迭代列表
                }
            }
        }
 
    }
 
    //非递归深度优先算法
    private void doIterator2(String rootPath) throws Exception {
        File rootFile = new File(rootPath);
        int level = 1;
        System.out.println(rootFile.getCanonicalFile());
 
        LinkedList<WrapperFileNodeLevel> list = new LinkedList<WrapperFileNodeLevel>();
        File[] childs = rootFile.listFiles();
        if (childs != null) {
            for (File child : childs) { // 1.先添加第1层的子节点到迭代列表里
                list.add(new WrapperFileNodeLevel(child, level + 1));
            }
        }
 
        WrapperFileNodeLevel wrap;
        while (!list.isEmpty()) { // 2. 开始迭代
            wrap = list.removeFirst(); // 移除并返回此列表的第一个元素
            if (wrap.file.isDirectory()) {
                System.out.println(convertLevel2Str(wrap.level) + "[" + wrap.file.getName() + "]");
            } else {
                System.out.println(convertLevel2Str(wrap.level) + wrap.file.getName());
            }
 
            childs = wrap.file.listFiles();
            if (childs != null) {
                int pos = 0;
                for (File child : childs) {
                    list.add(pos++, new WrapperFileNodeLevel(child, wrap.level + 1)); // 3.有子节点则加入迭代列表
                }
            }
        }
 
    }
 
    private String convertLevel2Str(int level) {
        StringBuilder sb = new StringBuilder("");
        for (int i = 0; i < level; i++) {
            if (i == level - 1) {
                sb.append("|-");
            } else {
                sb.append("  ");
            }
        }
 
        return sb.toString();
    }
 
    private class WrapperFileNodeLevel {
        final File file;
        final int level;
 
        /**
         * @param file
         * @param level
         */
        WrapperFileNodeLevel(File file, int level) {
            this.file = file;
            this.level = level;
        }
     }
 
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱游泳的老白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值