当节点不为空时,每次遍历现将节点值添加进list,之后,左子树补空,遍历左子树;右指数不空,遍历右子树;最终返回list。需要注意的是根节点为空的情况,在遍历之前,根节点为空,直接返回(全局)list。
public class Solution {
ArrayList list = new ArrayList<>(); //注意定义的位置,便于处理空树的情况
public ArrayList preorderTraversal(TreeNode root) {
if(root == null)
return list;
list.add(root.val);
if(root.left != null)
preorderTraversal(root.left);
if(root.right != null)
preorderTraversal(root.right);
return list;
}
}
主要采用数据结构栈来辅助实现。每pop一个节点(当前根节点),前提是栈不为空,先将节点右孩子入栈,再将左孩子入栈(前提是孩子存在),依次pop及push。
public class Solution {
ArrayList list = new ArrayList<>();
public ArrayList preorderTraversal(TreeNode root) {
if(root == null)
return list;
Stack stack = new Stack<>();
stack.push(root);
while(!stack.isEmpty()) {
TreeNode temp = stack.pop();
list.add(temp.val);
if(temp.right != null)
stack.push(temp.right);
if(temp.left != null)
stack.push(temp.left);
}
return list;
}
}
对应节点不空时,进行对应的左右递归遍历,然后list中加入根节点的值
public class Solution {
ArrayList list = new ArrayList<>();
public ArrayList postorderTraversal(TreeNode root) {
if(root == null)
return list;
if(root.left != null)
postorderTraversal(root.left);
if(root.right != null)
postorderTraversal(root.right);
list.add(root.val);
return list;
}
}
看的别人的思路
首先将节点入栈,栈不空的时候,判断栈顶节点是否有左右孩子,没有左右孩子这可以直接访问(值添加进list中,pop,改变当前访问的节点)或者是在此步之前访问的节点是该节点的孩子(孩子均被访问过了),也可以直接访问该节点,除此之外,需将节点的孩子按照右左的顺序入栈。
public class Solution {
ArrayList list = new ArrayList<>();
public ArrayList postorderTraversal(TreeNode root) {
if(root == null)
return list;
Stack stack = new Stack<>();
TreeNode pre = null;
stack.push(root);
while(!stack.isEmpty()) {
TreeNode cur = stack.peek(); //必要性 时间复杂度
if((cur.left == null && cur.right == null) || (pre!= null &&(pre == cur.right || pre == cur.left))) {
list.add(cur.val);
pre = cur;
stack.pop();
}
else {
if(cur.right != null)
stack.push(cur.right);
if(cur.left != null)
stack.push(cur.left);
}
}
return list;
}
}