算法通关村 —— 迭代实现二叉树的前中后序遍历

目录

迭代实现二叉树的前中后序遍历

一 迭代实现前序遍历

二 迭代实现中序遍历

三 迭代实现后序遍历


迭代实现二叉树的前中后序遍历

一 迭代实现前序遍历

前序遍历是中左右,如果当前节点还有左子树就一直向下找。直到当前节点没有左子树后再返回从最底层逐步向上向右找。则可写出如下代码:(注!代码中空节点不入栈)

public List<Integer> preorderTraversal(TreeNode root) {
    // 存放遍历结果的列表
    List<Integer> res = new ArrayList<>();
    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;
}

二 迭代实现中序遍历

再来看中序遍历,中序遍历顺序为左中右,先访问二叉树左子树的节点,然后一层一层向下访问,直到到达树左面的最底部,再开始处理节点(也就是把节点值存进res列表)。然后处理其父节点,再处理其父节点的右节点。处理完后再继续回到上一层的父节点,如此重复迭代而已。在使用迭代法写中序遍历时,就需要借用指针的遍历来帮助访问接待你,栈则用来处理节点上的元素。

具体实现代码如下:

public List<Integer> inorderTraversal(TreeNode root) {
    // 存放遍历结果的列表
    List<Integer> res = new ArrayList<>();
    if(root == null) return res;
    // 存放遍历到的节点的栈
    Deque<TreeNode> stack = new LinkedList<TreeNode>();
    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;
}

三 迭代实现后序遍历

这里介绍的是反转法来迭代实现后序遍历,我们知道后序遍历顺序为左右中,所以我们如果得到了中左右的遍历顺序结果,通过反转的方法便可得到后序遍历结果。所以方法很简单,只需改造以下前序遍历,让他先访问右节点便好。最后把结果反转一下就得到后序遍历结果了。如下图所示:

具体实现代码如下:

public List<Integer> postorderTraversal(TreeNode root) {
    // 存放遍历结果的列表
    List<Integer> res = new ArrayList<>();
    if(root == null) return res;
    // 存放遍历到的节点的栈
    Deque<TreeNode> stack = new LinkedList<>();
    TreeNode node = root;
    while(!stack.isEmpty() || node != null){
        while(node != null){
            // 一直迭代寻找右节点
            res.add(node.val);
            stack.push(node);
            node = node.right;
        }
        // 若无右节点则出栈寻找其左节点
        node = stack.pop();
        node = node.left;
    }
    // 将得到的中右左的前序遍历结果反转则得到左右中的后序遍历结果
    Collections.reverse(res);
    return res;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值