栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【JAVA】二叉树迭代遍历的统一写法(代码注释详解)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【JAVA】二叉树迭代遍历的统一写法(代码注释详解)

二叉树迭代遍历是用栈来代替递归,其中向下查询左节点进行入栈是统一的操作,我们需要思考合适进行结果写入以及出栈的操作,一个统一的模板可以帮助理清思路,详细注释都在代码里:
 
    private List iterateTemplate(TreeNode root) {
        Deque stack = new ArrayDeque<>();
        List resultList = new ArrayList<>();
        TreeNode curNode = root; // 当前节点
        while (!stack.isEmpty() || curNode != null) {
            if (curNode != null) {
               // 左节点入栈过程
            } else {
                // 从栈中取
            }
        }
        return resultList;
    }

    
    private List preOrderIterate(TreeNode root) {
        Deque stack = new ArrayDeque<>();
        List resultList = new ArrayList<>();
        TreeNode curNode = root;
        while (!stack.isEmpty() || curNode != null) {
            if (curNode != null) {
                stack.push(curNode);
                resultList.add(curNode.val);
                curNode = curNode.left;
            } else {
                // 从栈中取
                curNode = stack.pop();
                curNode = curNode.right;
            }
        }
        return resultList;
    }

    
    private List inorderIterate(TreeNode root) {
        Deque stack = new ArrayDeque<>();
        List resultList = new ArrayList<>();
        TreeNode curNode = root;
        while (!stack.isEmpty() || curNode != null) {
            if (curNode != null) {
                //【1】
                stack.push(curNode);
                curNode = curNode.left;
            } else {
                // 节点为空,进行出栈【2】
                curNode = stack.pop();
                resultList.add(curNode.val);
                if (curNode.right != null) {
                    //【3】
                    curNode = curNode.right;
                } else {
                    // 没有右节点时要置空,下一个元素从栈内拿
                    curNode = null;
                }
            }
        }
        return resultList;
    }

    
    private List postOrderIterate(TreeNode root) {
        List result = new ArrayList<>();
        Deque stack = new ArrayDeque<>();
        TreeNode curNode = root; // 标志当前节点(当节点进行入栈时不为空,节点为空时标志该出栈)
        TreeNode lastPopNode = null;// 记录上一个出栈的node
        while (!stack.isEmpty() || curNode != null) {
            if (curNode != null) {
                // 延左子树向下寻找【1】
                stack.push(curNode);
                curNode = curNode.left;
            } else {
                // curNode == null 表示左子树遍历到头/正在出栈
                curNode = stack.peek(); // 先不弹出,可能是第一次访问
                if (curNode.right == null || curNode.right == lastPopNode) {
                    // 没有右子树/右子树已访问过【3】
                    stack.pop(); // 可以弹出
                    lastPopNode = curNode;
                    result.add(curNode.val);
                    curNode = null; // 注意要把curNode置空
                } else {
                    // 有右子树且右子树未被访问过【2】
                    curNode = curNode.right; // 进入右子树
                }
            }
        }
        return result;
    }

TreeNode节点定义如下:

public class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

    TreeNode() {
    }

    TreeNode(int val) {
        this.val = val;
    }

    TreeNode(int val, TreeNode left, TreeNode right) {
        this.val = val;
        this.left = left;
        this.right = right;
    }
}

最重要的还是自己实践之后形成自己的经验

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/763641.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号