14.力扣-树-非递归遍历

力扣-树-非递归遍历

1.前序遍历(LeetCode 144)
——中、左、右

  • 解题思路:先找到最左下角结点,将节点压入堆栈,同时将节点加入遍历集中,这样就完成了中、左的顺序。知道找到最左下角后,pop栈顶在找其右结点即可,即完成了中、左、右的顺序。
  • (这个地方最好还是多拿几个例子试试,才能明白)
class Solution1 {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<Integer>();
        if (root == null) {
            return res;
        }

        Deque<TreeNode> stack = new LinkedList<TreeNode>();
        TreeNode node = root;
        while (!stack.isEmpty() || node != null) {
            //找到最左下角的结点
            while (node != null) {
                res.add(node.val);
                stack.push(node);
                node = node.left;
            }
            node = stack.pop();
            node = node.right;
        }
        return res;
    }
}

2.中序遍历(LeetCode 94)
——左、中、右

  • 解题思路:中序和前序的大体思路相同,只是在插入res集合的位置不同,要先找到左下角的结点后,先将左下角结点入栈
class Solution1 {
    public List<Integer> inorderTraversal(TreeNode root) {
        Deque<TreeNode> stack=new LinkedList<>();
        List<Integer> res=new ArrayList<>();
        if(root==null) return res;
        while(!stack.isEmpty()||root!=null){
            while(root!=null){
                stack.push(root);
                root=root.left;
            }
            root=stack.pop();
            res.add(root.val);
            root=root.right;
        }
        return res;
    }
}

3.后序遍历(LeetCode 145)
——左、右、中

  • 解题思路:后序遍历相比前、中序较为麻烦,也是先找到最左下角的结点,这里注意有一点不同的是在找其右结点的时候要分类讨论,详细见代码中的备注,写的比较清楚了(还是要多找几个例子自己试一下)
class Solution1 {
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<Integer>();
        if (root == null) {
            return res;
        }

        Deque<TreeNode> stack = new LinkedList<TreeNode>();
        TreeNode prev = null;
        while (root != null || !stack.isEmpty()) {
            //找到最左下角结点
            while (root != null) {
                stack.push(root);
                root = root.left;
            }
            root = stack.pop();
            //root==right是为了遍历右结点,root.tight==prev是为了能从深往浅返回去(已经遍历完左右结点回到该结点时)
            if (root.right == null || root.right == prev) {
                res.add(root.val);
                prev = root;
                //root=null为了防止进入上面的循环
                root = null;
            }
            //如果有右节点就要将目前的结点压回栈,因为按照后序遍历的顺序,该节点要在右结点后被遍历
            else {
                stack.push(root);
                root = root.right;
            }
        }
        return res;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值