二叉树的后序遍历 --java

给定一个二叉树,返回它的 后序 遍历。在这里插入图片描述
利用递归,先递归左节点然后递归右节点,最后访问节点值。

class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        LinkedList<Integer> list = new LinkedList<Integer>();
        if(root == null) return list;
        LRD(root,list);
        return list;
    }
    public static void LRD(TreeNode root,List<Integer> list){
        if(root.left != null){
            LRD(root.left,list);
        }
        if(root.right != null){
            LRD(root.right,list);
        }
        list.add(root.val);
    }
}

利用栈保存节点。
1、左孩子节点不为空时先入栈。
2、左孩子节点为空时,右孩子节点入栈。
3、当左右孩子节点都为空的时候,出栈,取节点值

直接写上述步骤会遇到一个问题,当访问完,左右孩子节点时候,如何判断访问该节点,因为该节点左右孩子都不为空。 所以这里入栈的时候,节点的左孩子存在先入栈,然后将node.left = null ,同样右孩子节点也置空(关联节点先入栈再删除,并不影响),这样就可以访问中间节点。
故,孩子节点已入栈则将节点的相关孩子节点指针置空。

class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {

        LinkedList<Integer> list = new LinkedList<Integer>();
        if(root == null) return list;
        Stack<TreeNode> stack = new Stack<TreeNode>();

        stack.push(root);  
        while(!stack.isEmpty() ) { 
            TreeNode node = stack.peek();   
        	if(node.left != null) {
        		TreeNode temp = node.left;
        		stack.push(temp);
        		node.left = null;   //左孩子节点进栈后,将左孩子节点置空,防止节点重复访问
        	}else if (node.right != null) {
        		TreeNode temp = node.right;
        		stack.push(temp);
        		node.right = null;
        	}else {
        		stack.pop();
        		list.add(node.val);
        	}
       	
        }
        return list;
        
    }
}

访问中间节点,然后右孩子节点,接着左孩子节点,这样访问则与后续遍历完全相反。
将这种访问,值每次插入到list的第一个位子。这样list就是倒序,就可以实现后续遍历。
这种代码写法将先序遍历修改一下就可以,现需遍历是右孩子节点先入栈,这里是左孩子节点先入栈。

public List<Integer> postorderTraversal(TreeNode root)
{
   LinkedList<Integer> list = new LinkedList<Integer>();
   Stack<TreeNode> stack = new Stack<>();

   if (root == null)
       return list;

   stack.push(root);

   while (!stack.isEmpty())
   {
       TreeNode node = stack.pop();

       list.add(0,node.val);

       if (node.left != null)
           stack.push(node.left);

       if (node.right != null)
           stack.push(node.right);

   }

   return list;
}
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值