二叉树的前序,后序遍历,中序遍历(非递归) Java

二叉树的三种遍历如果用递归写都很简单,代码几乎都没有变化

前序遍历

非递归的前序遍历思路如下:
前序遍历:root -> left -> right
用栈保存左右节点
每次先取出栈顶元素(root),加入结果
再把栈顶元素的左右节点加入栈
要想用栈实现先遍历左子树再遍历右子树,那么添加到栈的时候就要反过来添加,先添加右子树再添加左子树
返回结果

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public List<Integer> preorder(TreeNode root) {
    List<Integer> result = new ArrayList<>();
    Stack<TreeNode> stack = new Stack<>();
    stack.push(root);
    while (!stack.isEmpty()) {
        TreeNode node = stack.pop();
        if (node == null) continue;
        result.add(node.val);
        stack.push(node.right);  // 先右后左,保证左子树先遍历
        stack.push(node.left);
    }
    return result;
}
后序遍历

left -> right -> root
先来回顾一下前序遍历 root -> left -> right
这样看两条式子有点像,root都是一头一尾,但中间有点不太一样,如果把前序变成root -> right -> left的话那就和后序遍历完全逆序了
所以一种巧妙的思路就是把前序遍历稍微改一改,然后把结果集逆序

代码:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
 public List<Integer> postorder(TreeNode root) {
    List<Integer> result= new ArrayList<>();
    Stack<TreeNode> stack = new Stack<>();
    stack.push(root);
    while (!stack.isEmpty()) {
        TreeNode node = stack.pop();
        if (node == null) continue;
        result.add(node.val);
        stack.push(node.left);
        stack.push(node.right);
    }
    Collections.reverse(result);
    return result;
}
中序遍历

left -> root-> right
也就是说要一直找到树的最左节点,再访问其父节点最后访问父节点右子树

代码:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public List<Integer> inorder(TreeNode root) {
    List<Integer> result= new ArrayList<>();
    if (root == null){
    	return result;
    }
    Stack<TreeNode> stack = new Stack<>();
    TreeNode current = root;
    while (current != null || !stack.isEmpty()) {
        while (current != null) {
            stack.push(current);
            //一直找到最左,先不管右边
            current = current.left;
        }
        TreeNode node = stack.pop();
        result.add(node.val);
        //中序遍历,最后访问右边
        current = node.right;
    }
    return result;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值