博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
二叉树的后序遍历 Binary Tree Postorder Traversal
阅读量:6118 次
发布时间:2019-06-21

本文共 2121 字,大约阅读时间需要 7 分钟。

  hot3.png

问题:

Given a binary tree, return the postorder traversal of its nodes' values.

For example:

Given binary tree {1,#,2,3},

   1    \     2    /   3

return [3,2,1].

Note: Recursive solution is trivial, could you do it iteratively?

解决:

① 后根遍历,递归方法。

/**

 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */

public class Solution {//1ms

    public List<Integer> postorderTraversal(TreeNode root){
        List<Integer> res = new ArrayList<>();
        postorder(root,res);
        return res;
    }
    public void postorder(TreeNode root,List<Integer> res){
        if (root == null) return;
        postorder(root.left,res);
        postorder(root.right,res);
        res.add(root.val);
    }
}

② 非递归方法,使用栈,后根遍历的顺序是:左-->右-->根,可以先根据:根-->右-->左的顺序来遍历,然后使用链表保存的结果是反序存放的,所以只需要将结果插入到链表的头部即可。

class Solution { //1ms

    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        Stack<TreeNode> stack = new Stack<>();
        if(root != null){
            stack.push(root);
            while(! stack.isEmpty()){
                TreeNode cur = stack.pop();
                res.add(0,cur.val);
                if(cur.left != null) stack.push(cur.left);
                if(cur.right != null) stack.push(cur.right);
            }
        }
        return res;
    }
}

③ 非递归方法,使用stack。

【注】

首先要搞清楚先序、中序、后序的非递归算法共同之处:用栈来保存先前走过的路径,以便可以在访问完子树后,可以利用栈中的信息,回退到当前节点的双亲节点,进行下一步操作。

后序遍历的非递归算法是三种顺序中最复杂的,原因在于,后序遍历是先访问左、右子树,再访问根节点,而在非递归算法中,利用栈回退到时,并不知道是从左子树回退到根节点,还是从右子树回退到根节点,如果从左子树回退到根节点,此时就应该去访问右子树,而如果从右子树回退到根节点,此时就应该访问根节点。所以相比前序和后序,必须得在压栈时添加信息,以便在退栈时可以知道是从左子树返回,还是从右子树返回进而决定下一步的操作

在出栈的时候需要分情况一下:

1)如果当前栈顶元素的右结点存在并且还没访问过(也就是右结点不等于上一个访问结点),那么就把当前结点移到右结点继续循环;
2)如果栈顶元素右结点是空或者已经访问过,那么说明栈顶元素的左右子树都访问完毕,应该访问自己继续回溯了

class Solution {//2ms

    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        Stack<TreeNode> stack = new Stack<>();
        TreeNode pre = null;
        while(root != null || ! stack.isEmpty()){
            if(root != null){
                stack.push(root);
                root = root.left;
            }else{
                TreeNode cur = stack.peek();
                if (cur.right != null && pre != cur.right) {
                    root = cur.right;
                }else{
                    stack.pop();
                    res.add(cur.val);
                    pre = cur;
                }
            }
        }
        return res;
    }
}

④ 还有一个Morris方法

转载于:https://my.oschina.net/liyurong/blog/1563420

你可能感兴趣的文章
linecache模块的使用
查看>>
我的友情链接
查看>>
Outlook Express收到邮件但看不到附件问题解决
查看>>
响应性web设计实战总结
查看>>
pcDuino的linux移植四简单驱动开发
查看>>
Rreset DC Clean KDC
查看>>
路由器、交换机配置前准备工作_01
查看>>
oracle数据文件recover恢复过程
查看>>
AMD64与IA64的区别-64位操作系统
查看>>
我的友情链接
查看>>
配置远程桌面服务会话的超时设置和重新连接设置
查看>>
linux硬盘安装的方法
查看>>
Android判断、创建和删除快捷方式
查看>>
云平台编程与开发(二):X5Cloud云平台SDK包概述
查看>>
Android图片失真问题
查看>>
我的友情链接
查看>>
通过路由配置提高Wi-Fi速度和距离
查看>>
使用Gradle构建Java项目
查看>>
Leetcode PHP题解--D26 766. Toeplitz Matrix
查看>>
爬虫简单入门-接口寻找调用
查看>>