递归,所有的递归遍历都可以这样写,只需要调整最后三句话的顺序。不管是什么遍历,走的路程都是一样的,只是再第几次碰到节点的时候处理。中序,就是第二次。
class Solution {
private List<Integer> list = new ArrayList();
public List<Integer> inorderTraversal(TreeNode root) {
InOrder(root);
return list;
}
private void InOrder(TreeNode root){
if(root == null){
return;
}
inorderTraversal(root.left);
list.add(root.val);
inorderTraversal(root.right);
}
}
中序的非递归实现:
class Solution {
private List<Integer> list = new ArrayList();
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList();
Stack<TreeNode> stack = new Stack();
TreeNode p = root;
while(p!=null || !stack.isEmpty()){
while(p!=null){//一直走到最左保存下来
stack.push(p);
p = p.left;
}
if(!stack.isEmpty()){
p = stack.pop();//第二次碰到的时候
list.add(p.val);
p=p.right;
}
}
return list;
}
}
前序非递归
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList();
Stack<TreeNode> stack = new Stack();
TreeNode p = root;
while(p!=null || !stack.isEmpty()){
while(p!=null){
list.add(p.val);//和中序非递归,就这一个地方不一样,第一次碰到的时候保存。
stack.push(p);
p = p.left;
}
if(!stack.isEmpty()){
p = stack.pop();
p = p.right;
}
}
return list;
}
}
后序遍历套用前序遍历,因为前序是根左右,改成根右左,最后反转一下成左右根。
所以后序的递归写法我写成了这样,同理非递归也可以改改中序。
class Solution {
private List<Integer> list = new ArrayList();
public List<Integer> postorderTraversal(TreeNode root) {
inOrder(root);
if(list!=null){
Collections.reverse(list); //反转
}
return list;
}
private void inOrder(TreeNode root){
if(root == null){
return;
}
list.add(root.val); //根节点
inOrder(root.right); //右子树
inOrder(root.left); //左子树
}
}