java 递归及迭代 二叉树的后序遍历
给定一个二叉树,返回它的 后序 遍历。
示例:
输入: [1,null,2,3]
1
2
/
3
输出: [3,2,1]
进阶: 递归算法很简单,你可以通过迭代算法完成吗?
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
}
}
-
首先,我们使用递归的方式遍历
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
// 定义一个存放结果的集合
private List list=new ArrayList();
public List<Integer> postorderTraversal(TreeNode root) {
if(root == null) return list;
// 后序遍历首先保存左子树
postorderTraversal(root.left);
// 保存右子树
postorderTraversal(root.right);
// 保存根节点
list.add(root.val);
return list;
}
}
-
进阶,使用迭代的方式
- 取巧的方式,也是我最先想到的方式
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
/**
* 前序是 根=>左节点=>右节点
* 后序是 左节点=>右节点=>根
* 那我先获取 根=>右节点=>左节点 是不是就是后序排序的倒序?
*/
public List<Integer> postorderTraversal(TreeNode root) {
// 定义一个存放结果的集合
LinkedList<Integer> list=new LinkedList<Integer>();
// 定义待处理节点的栈
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode p = root;
while (p != null) {
// 后序遍历最后保存根节点,将其压栈结果
list.push(p.val);
if (p.left!= null)
stack.push(p.left);
// 将右节点赋值继续操作
p = p.right;
// 如果右节点为空,从栈顶获取一个最近的一个节点操作(当栈中也没有节点时,树已遍历完)
if (p == null && stack.size() > 0) {
p = stack.pop();
}
}
return list;
}
}
- 常规的方式,需要同时保存根节点及右节点,但从栈中取出时直接获取右节点,逻辑稍复杂。此时需要使用一个对象记录上一个出栈加入结果集的结点,与当前结点比较,如果是当前结点的右节点,说明其左右结点均已访问,将当前结点出栈。
public List<Integer> postorderTraversal(TreeNode root) {
// 定义一个存放结果的集合
List<Integer> list=new ArrayList<Integer>();
// 定义待处理节点的栈
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode p = root;
// 最后加入结果集的节点
TreeNode pro=null;
while (p != null) {
// 因为后序先处理最左节点,父节点也处于待处理阶段,所以不管三七二十一先将节点入栈
stack.push(p);
p=p.left;
// 如果左节点为空,从栈顶获取一个最近的一个节点操作(当栈中也没有节点时,树已遍历完)
while (p == null && stack.size() > 0) {
// 获取栈顶元素
p = stack.peek();
// 如果栈顶元素的右节点为空或右节点为上次结果的值,当前节点为已遍历完左右节点的父节点,直接出栈取值
if((p=p.right)==null || p==pro){
pro=stack.pop();
list.add(pro.val);
p=null;
}
}
}
return list;
}
执行结果:
下一篇:
【数据结构】栈的代码实现
