二叉树遍历LeetCode#144 #94 #145 (前中后序遍历)

  • 题目:二叉树的前序遍历(递归以及非递归方法)
  • 难度:Medium
  • 思路:递归很简单,非递归需要借助栈来实现
  • 代码:
    递归代码
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    //递归方法
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<Integer>();
        if(root == null){
            return result;
        }
        recursion(root,result);
        return result;
    }

    public void recursion(TreeNode node, List<Integer> list){
        if(node == null){
            return;
        }else{
            //先递归左子树,再递归右子树
            list.add(node.val);
            recursion(node.left, list);
            recursion(node.right, list);
        }
    }

}

非递归代码

public class Solution {
    //递归方法
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<Integer>();
        if(root == null){
            return result;
        }
        //利用双向链表做栈使用
        LinkedList<TreeNode> stack = new LinkedList<>();
        stack.push(root);
        while(!stack.isEmpty()){
            TreeNode node = stack.pop();
            result.add(node.val);
            //注意:将右子树先压入栈(先序遍历的顺序是先跟节点,再左子树,再右子树)
            if(node.right != null){
                stack.push(node.right);
            }
            if(node.left != null){
                stack.push(node.left);
            }
        }
        return result;
    }

}
  • 题目:二叉树的后序遍历(递归与非递归方式)
  • 难度:Medium
  • 思路:后序遍历的递归方式与前序相似,只需要将跟节点的访问调整到左右子树访问之后;而非递归
  • 代码:
    递归方法
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        if(root == null){
            return result;
        }
        recursion(root, result);
        return result;
    }

    public void recursion(TreeNode node, List<Integer> list){
        if(node == null){
            return;
        }else{
            recursion(node.left, list);
            recursion(node.right, list);
            list.add(node.val);
        }
    }
}

非递归方法

public class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        if(root == null){
            return result;
        }
        LinkedList<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        TreeNode curr = null;
        TreeNode pre = null;
        while(!queue.isEmpty()){
            curr = queue.peekLast();
            //1.当前节点为叶子节点时,该节点需要加入result列表
            //2.上一个访问的节点是当前节点的左孩子或者右孩子时,说明该节点的左右子树节点都已经被访问过,该节点也被加入result列表
            //对于第2点,可能存在疑问:如果当前节点有两个孩子,应该需要判断它两个孩子都被访问呀?,事实是,我们在入队列的时候是右孩子先入队列,然后左孩子再入队列。curr节点的右孩子等于pre的时候,说明curr节点的左孩子已经被访问了或者curr节点没有左孩子;curr节点的左孩子等于pre的时候,说明curr节点只有左孩子
            if((curr.left == null && curr.right == null) || 
                (pre != null &&(curr.left == pre || curr.right == pre))){
                result.add(curr.val);
                pre = queue.pollLast();
            }else{
                if(curr.right != null){
                    queue.offer(curr.right);
                }
                if(curr.left != null){
                    queue.offer(curr.left);
                }
            }
        }
        return result;
    }
}
  • 题目:中序遍历二叉树(递归和非递归)
  • 难度:Medium
  • 思路:递归方式遍历与前后序基本一样,只是改变访问根节点的位置;非递归方式,我觉得比较难,主要是想统一三种遍历的代码,对中序遍历来讲,这里使用到一个trick就是将curr.left将入栈之后,就把curr.left设置为null
  • 代码:
    递归
public class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        if(root == null){
            return result;
        }
        recursion(root, result);
        return result;
    }
    public void recursion(TreeNode node, List<Integer> list){
        if(node == null){
            return;
        }else{
            recursion(node.left, list);
            list.add(node.val);
            recursion(node.right, list);
        }
    }

}

非递归

public class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        if(root == null){
            return result;
        }
        LinkedList<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        TreeNode curr = null;
        while(!queue.isEmpty()){
            curr = queue.peekLast();
            System.out.println("进入while循环");
            if(curr.left != null){
                queue.offer(curr.left);
                curr.left = null;//这个trick非常重要,不然就会死循环
            }else{
                result.add(curr.val);
                curr = queue.pollLast();
                if(curr.right != null){
                    queue.offer(curr.right);
                }
            }

        }
        return result;
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值