题目:给定一个二叉树,返回它的 后序 遍历
思路:这个题之前总结二叉树的相关知识的时候写过,但是后序遍历比较难,所有在这里单独把后序遍历拿出来总结下。以下的代码来自leetcode评论中大神的代码,分别使用递归,迭代和另外一种方法进行后序遍历。
代码:
(1)递归写法
class Solution {
public List<Integer> res = new ArrayList<Integer>();//注意这一部分要写在这个函数的外部
public List<Integer> postorderTraversal(TreeNode root) {//递归写法
if(root == null)
return res;
postorderTraversal(root.left);
postorderTraversal(root.right);
res.add(root.val);
return res;
}
}
(2)迭代写法
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {//非递归写法
List<Integer> res = new ArrayList<Integer>();
if(root == null)
return res;
Stack<TreeNode> stack = new Stack<TreeNode>();//使用栈
TreeNode pre = null;
stack.push(root);
while(!stack.isEmpty()){
TreeNode curr = stack.peek();
if((curr.left == null && curr.right == null) ||
(pre != null && (pre == curr.left || pre == curr.right))){
//如果当前结点左右子节点为空或上一个访问的结点为当前结点的子节点时,当前结点出栈
res.add(curr.val);
pre = curr;
stack.pop();
}else{
if(curr.right != null) stack.push(curr.right); //先将右结点压栈
if(curr.left != null) stack.push(curr.left); //再将左结点入栈
}
}
return res;
}
}
(3)
这种思路和剑指32题中的思路是一样的,只不过最后反转链表的做法不一样。同样是使用栈,添加节点时把后序当作:根->右->左,然后再反转一下即可。根左右反转过来就是左右根。
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<Integer>();
if(root == null)
return res;
Stack<TreeNode> stack = new Stack<TreeNode>();
stack.push(root); //根节点入栈
while(!stack.isEmpty()){
TreeNode node = stack.pop(); //根节点出栈
if(node.left != null) stack.push(node.left);//和传统先序遍历不一样,先将左结点入栈
if(node.right != null) stack.push(node.right);//后将右结点入栈
res.add(0,node.val); //逆序添加结点值.每次都添加到集合的头部,其实也可以直接用LinkedList的addFirst().
//反转
//Collections.reverse(res); 或者可以这样反转链表
}
return res;
}
}
和之前前序中序类似的写法:
class Solution {
public List<Integer> postorderTraversal(TreeNode pTreeNode) {
List<Integer>res=new ArrayList<>();
Stack<TreeNode> stack = new Stack<TreeNode>();
while(pTreeNode!=null || !stack.isEmpty()){ //当前节点不为空或者栈中不为空
while(pTreeNode!=null){
res.add(0,pTreeNode.val);
stack.push(pTreeNode); //将当前节点放入栈中
pTreeNode = pTreeNode.right; //处理右节点
}
if(!stack.isEmpty()){ //当处理完左结点之后
pTreeNode = stack.pop(); //处理左节点
pTreeNode = pTreeNode.left;
}
}
return res;
}
}