首页 > 试题广场 >

二叉树的后序遍历

[编程题]二叉树的后序遍历
  • 热度指数:68884 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
用递归的方法对给定的二叉树进行后序遍历。
例如:
给定的二叉树为{1,#,2,3},

返回[3,2,1].
示例1

输入

{1,#,2,3}

输出

[3,2,1]

说明:本题目包含复杂数据结构TreeNode,点此查看相关信息
public class Solution {
    /**
     * 
     * @param root TreeNode类 
     * @return int整型ArrayList
     */
    public ArrayList<Integer> postorderTraversal (TreeNode root) {
        ArrayList<Integer> res=new ArrayList<>();
        postOrder(root,res);
        return res;
        // write code here
    }
    public void postOrder(TreeNode root,ArrayList<Integer> res){
        if(root==null) return;
        postOrder(root.left,res);
        postOrder(root.right,res);
        res.add(root.val);
    }
}
发表于 2021-09-08 20:59:52 回复(0)
/**
 * Definition for binary tree
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
import java.util.Stack;
import java.util.*;
public class Solution {
    public ArrayList<Integer> postorderTraversal(TreeNode root) {
        ArrayList<Integer> res = new  ArrayList<>();
        Stack<TreeNode> s =  new Stack<>();
        TreeNode p = root;
        TreeNode r = null;
        while(p!=null||!s.isEmpty()){
            if(p!=null){
                s.push(p);
                p = p.left;
            }else{
                p = s.pop();
                if(p.right!=null&&p.right!=r){
                    s.push(p);
                    p = p.right;
                    s.push(p);
                    p = p.left;
                }else{
                    
                    res.add(p.val);
                    r = p;
                    p = null;
                }
            }
        }
        return res;
    }
    }
发表于 2020-03-14 16:34:15 回复(0)
思路: 
 public ArrayList<Integer> postorderTraversal(Node root) {

        ArrayList<Integer> orders = new ArrayList<>();

        if (root == null ) return orders;
        Stack<Node> nodes = new Stack<>();
        nodes.push(root);
        Node previous = null;
        while(!nodes.isEmpty()){
            Node current = nodes.peek();
            if (previous == null || previous.left == current || previous.right == current){
// traversing down the tree;
//if current node is the toot node or it has child node
                if (current.left != null){
                    // add the left node until the deepest
                    nodes.push(current.left);
                }else if(current.right != null){
                    // add the right node 
                    nodes.push(current.right);
                }
            }else if(current.left == previous){
                // traversing up the tree
                if (current.right !=null){
                    nodes.push(current.right);
                }
            }else{
                // the leaf node
                orders.add(current.value);
                nodes.pop();
            }
            previous = current;
        }
        return orders;
    }


发表于 2020-03-05 06:49:16 回复(0)
/**
 * Definition for binary tree
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
import java.util.ArrayList;
public class Solution {
    
    public ArrayList<Integer> postorderTraversal(TreeNode root) {
        ArrayList<Integer> list=new ArrayList<Integer>();
        if(root==null)
            return list;
        function(list,root);
        return list;
    }
    public void function(ArrayList<Integer> list,TreeNode root){
        if(root==null)
            return;
        if(root.left!=null){
            function(list,root.left);
        }
        if(root.right!=null){
            function(list,root.right);
        }
        list.add(root.val);
    }
}

发表于 2020-02-21 14:44:44 回复(0)
这里使用一个set来记录访问过的节点来判断子节点是否访问过,因为HashSet支持null值,所以空值也可以判断。
import java.util.*;

public class Solution {
    public ArrayList<Integer> postorderTraversal(TreeNode root) {
        ArrayList<Integer> list = new ArrayList<>();
        if(root == null) return list;
        Stack<TreeNode> stack = new Stack<>();
        Set<TreeNode> set = new HashSet<>();
        set.add(root);
        stack.push(root);
        while(!stack.isEmpty()){
            TreeNode node = stack.pop();
            if(set.contains(node.left) && set.contains(node.right)){
                list.add(node.val);
                continue;
            }
            set.add(node.right);
            set.add(node.left);
            stack.push(node);
            if(node.right!=null) stack.push(node.right);
            if(node.left!=null) stack.push(node.left);
        }
        return list;
    }
}


编辑于 2019-12-30 14:32:37 回复(0)
/** 采用 根——右——左 的顺序进行遍历,利用栈实现
    遍历过程中将元素值添加到指定ArrayList中
    最后将列表翻转即可,间接实现对 左——右——根 的访问
    */
public class Solution {
    public ArrayList<Integer> postorderTraversal(TreeNode root) {
        Stack<TreeNode> stack=new Stack<TreeNode>();
        ArrayList<Integer> list=new ArrayList<Integer>();
        if(root!=null){
            stack.push(root);
            while(stack!=null && stack.size()!=0){
                TreeNode p=stack.pop();
                list.add(p.val);
                if(p.left!=null){
                    stack.push(p.left);
                }
                if(p.right!=null){
                    stack.push(p.right);
                }
            }
            Collections.reverse(list);
        }
        return list;
    }
}

发表于 2019-11-21 10:48:40 回复(0)
import java.util.ArrayList;
import java.util.Stack;
public class Solution {
    public ArrayList<Integer> postorderTraversal(TreeNode root) {
         ArrayList<Integer> list = new ArrayList<Integer>();
         //非递归实现
          if(root!=null){
              Stack<TreeNode> s1=new Stack<>();
              Stack<TreeNode> s2=new Stack<>();
              s1.push(root);
              while(!s1.isEmpty()){
                  root=s1.pop();
                  s2.push(root);
                  if (root.left != null) {                     s1.push(root.left);                 }                 if (root.right != null) {                     s1.push(root.right);                 }             }               while (!s2.isEmpty()) {                 list.add(s2.pop().val);             }
              }
        return list;
        
          }
    
}

发表于 2019-03-25 21:26:15 回复(0)

题目描述

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?

解题思路

就是二叉树的后序遍历,它的意思是,递归程序没啥意思,要不你用非递归来实现一个?

我们知道,递归就是系统栈实现的,那么其实对于本题,我倾向于自己用一个栈来模拟系统栈,这样,无论是前序中序还是后序,改代码跟递归版本是一样,具有较强的通用性,至于另外的解法,每种都不一样,导致不好记忆。

代码提交

import java.util.*;
class Command{
    public String str;
    public TreeNode node;
    public Command(String str,TreeNode node){
        this.str = str;
        this.node = node;
    }
}
public class Solution {
    public ArrayList postorderTraversal(TreeNode root) {
        ArrayList res = new ArrayList();
        if(root == null){
            return res;
        }
        Stack stack = new Stack();
        //遇到“go”则添加左右孩子以及自己入栈
        //遇到“print”则添加进结果集
        stack.push(new Command("go",root));
        while(!stack.isEmpty()){
            Command c = stack.pop();
            if(c.str == "go"){
                //先自己
                stack.push(new Command("print",c.node));
                //再右
                if(c.node.right != null){
                    stack.push(new Command("go",c.node.right));
                }
                //再左
                if(c.node.left != null){
                    stack.push(new Command("go",c.node.left));
                }
                //出栈的顺序必然是左-右-中,即后序遍历顺序
            }else{
                res.add(c.node.val);
            }
        }
        return res;
    }
}

我们要想改成前序或者中序遍历,只需要将stack.push(new Command("print",c.node));调换一下位置即可,十分方便,这样对递归的实现原理的理解也加深了。

编辑于 2019-03-23 20:45:43 回复(0)
后序遍历,可以利用先序遍历的思路,根->左结点->右节点,我们就来个反其道而行之,根->右->左,压栈,最后出栈就是左->右->根,不就是后序了嘛,代码如下
import java.util.ArrayList;
import java.util.Stack;
public class Solution {
   public ArrayList<Integer> postorderTraversal(TreeNode root) {
        ArrayList<Integer> list = new ArrayList<Integer>();
        Stack<TreeNode> s = new Stack<TreeNode>();
        Stack<Integer> sval = new Stack<Integer>();
        while(root!=null || !s.isEmpty()){
            while(root!=null){
                s.push(root.left);
                sval.push(root.val);
                root = root.right;
            }
            root = s.pop();
        }
        while(!sval.isEmpty())
            list.add(sval.pop());
        return list;
    }

}
如果明白了上面压栈的做法,那么稍微改一下,就更简洁了
public ArrayList<Integer> postorderTraversal(TreeNode root) {
      ArrayList<Integer> list = new ArrayList<Integer>();
        Stack<TreeNode> s = new Stack<TreeNode>();
        while(root!=null || !s.isEmpty()){
            while(root!=null){
                s.push(root.left);
                list.add(0, root.val);
                root = root.right;
            }
            root = s.pop();
        }
        return list;
    }

编辑于 2018-09-01 01:22:21 回复(0)
import java.util.*;

public class Solution {
    public ArrayList<Integer> postorderTraversal(TreeNode root) {
        ArrayList<Integer> res = new ArrayList<>();
        if (root == null) return res;
        if (root.left == null && root.right == null) {
            res.add(root.val);
        } else if (root.left != null) {
            res.addAll(postorderTraversal(root.left));
            res.addAll(postorderTraversal(root.right));
            res.add(root.val);
        } else if (root.right != null) {
            res.addAll(postorderTraversal(root.right));
            res.add(root.val);
        }
        return res;
    }
}

使用递归的方式进行遍历
后序遍历的访问顺序使左右根,即先左儿子,再右儿子,最后根节点
由于遍历儿子节点跟遍历根节点是一样的情况,所以使用递归可以很容易的解答
发表于 2018-06-29 13:06:29 回复(0)
import java.util.*;//递归比较省心
public class Solution {
    public ArrayList<Integer> postorderTraversal(TreeNode root) {
        ArrayList<Integer> al = new ArrayList<Integer>();
        if(root==null)return al;
        al.addAll(postorderTraversal(root.left));
        al.addAll(postorderTraversal(root.right));
        al.add(root.val);
        return al;
    }
}

发表于 2018-06-09 16:34:53 回复(0)
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
import java.util.Stack;
import java.util.ArrayList;
import java.util.List;
class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        ArrayList<Integer> result = new ArrayList<>();
        if(root == null)
            return result;
        // nStack 存放树节点
        Stack<TreeNode> nStack = new Stack<>();
        // iStack 为存放状态的辅助栈,label表示nStack栈顶结点的状态。
        // state = 0 时,表示该节点左右结点都没有遍历过
        // state = 1 时,表示该结点左结点遍历过,右结点没有遍历过
        // state = 2 时,表示该结点左右结点都遍历过
        Stack<Integer> iStack = new Stack<>();
        // 首先压入根节点
        nStack.push(root);
        // 此处压入的0为占位符
        iStack.push(0);
        // label 标注此时nStack栈顶结点的状态
        int label = 0;
        while(!nStack.isEmpty()){
            // 获取栈顶结点
            TreeNode node = nStack.peek();
            // 根据状态标签判断如何处理该结点
            if(label == 2 || (label == 1 && node.right == null) || (node.left == null && node.right == null)){
                // 栈顶弹出后,需要从状态位辅助栈获取最新标签
                label = iStack.pop();
                result.add(nStack.pop().val);
            }else if(label == 0 && node.left != null){
                iStack.push(1);
                nStack.push(node.left);
                // 当压入新节点后,nStack栈顶改变,所以要改变此时的状态标签,label = 0
                label = 0;
            }else if(label == 0 && node.left == null){
                iStack.push(2);
                nStack.push(node.right);
                label = 0;
            }else if(label == 1){
                iStack.push(2);
                nStack.push(node.right);
                label = 0;
            }
            
        }
        return result;
    }
}

发表于 2018-05-30 20:45:54 回复(0)
public ArrayList postOrderTraversalByIterative(TreeNode root) {
    ArrayList returnList = new ArrayList(); if (root == null) { return returnList;
    }
    Stack stack = new Stack();
    stack.push(root); 
    // 当前节点  
    TreeNode pCur; 
    // 上一个访问的节点  
    TreeNode preNode = null; 
    while (!stack.empty()) {
        pCur = stack.lastElement(); if ((pCur.left == null && pCur.right == null)
                || (preNode != null && (pCur.right == preNode || pCur.left == preNode))) {
            returnList.add(pCur.val);
            preNode = pCur;
            stack.pop();
        } else { if (pCur.right != null) {
                stack.push(pCur.right);
            } if (pCur.left != null) {
                stack.push(pCur.left);
            }
        }
    } return returnList;
}

编辑于 2018-05-17 14:41:42 回复(0)
/**
 * Definition for binary tree
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
import java.util.*;
public class Solution {
    public ArrayList<Integer> postorderTraversal(TreeNode root) {
        if (root == null) {
        return new ArrayList<>();
    }
    ArrayList<Integer> list = new ArrayList<>();
    list.addAll(postorderTraversal(root.left));
    list.addAll(postorderTraversal(root.right));
    list.add(root.val);
    return list;
    }
}

发表于 2018-03-06 10:25:45 回复(0)
import java.util.ArrayList;
import java.util.Stack;
public class Solution {
    public ArrayList<Integer> postorderTraversal(TreeNode root) {
       ArrayList<Integer> postOrderList = new ArrayList<Integer>();
        if(root == null) return postOrderList;
        Stack<TreeNode> stack1 = new Stack<TreeNode>();
        Stack<TreeNode> stack2 = new Stack<TreeNode>();

        stack1.push(root);
        while (!stack1.isEmpty()){
            TreeNode node = stack1.pop();
            stack2.push(node);
            if(node.left != null) stack1.push(node.left);
            if(node.right != null) stack1.push(node.right);
        }

        while (!stack2.isEmpty()){
            TreeNode node = stack2.pop();
            postOrderList.add(node.val);
        }
        return postOrderList; 
    }
}

发表于 2018-01-01 21:53:24 回复(0)
public ArrayList<Integer> postorderTraversal(TreeNode root) {
        ArrayList<Integer> ret = new ArrayList<Integer>();
        if(root == null) return null;
        Stack<TreeNode> stack = new Stack<TreeNode>();
        TreeNode cur = root , lastVisitNode = null;
        while(cur != null){
            stack.add(cur);
            cur = cur.left;
        }
        while(!stack.empty()){
            cur = stack.peek();
            if(cur.right == null || cur.right == lastVisitNode){
                //当右侧节点为空 或者为访问过的节点的时候
                stack.pop();
                ret.add(cur.val);
                lastVisitNode = cur;
            }
            else{ //节点不为空 且 上次访问的是左树
                cur = cur.right;
                while(cur != null){
                    stack.add(cur);
                    cur = cur.left;
                }
            }
        }
        return ret;
    }
编辑于 2017-12-18 16:58:45 回复(0)
//后序遍历,递归解法
import java.util.*;

public class Solution {
    public ArrayList<Integer> postorderTraversal(TreeNode root) {
        ArrayList<Integer> resultList = new ArrayList<Integer>();
        if(root == null){
            return resultList;
        }
        getResult(root,resultList);
        return resultList;
    }
    
    public void getResult(TreeNode root , ArrayList<Integer> resultList){
        if(root.left != null){
            getResult(root.left,resultList);
        }
        if(root.right != null){
            getResult(root.right,resultList);
        }
        resultList.add(root.val);
    }
}

发表于 2017-09-01 16:06:06 回复(0)
/**
 * Definition for binary tree
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
import java.util.ArrayList;
public class Solution {
    ArrayList<Integer> list = new ArrayList<>();
    public ArrayList<Integer> postorderTraversal(TreeNode root) {
        if(root == null)
            return list;
        postorderTraversal(root.left);
        postorderTraversal(root.right);
        list.add(root.val);
        return list;
    }
}

发表于 2017-08-12 18:15:53 回复(0)