要求大家掌握一下非递归的遍历方式,请大家给出自己的代码,并且认准自己的模版,以后就要这个模版,切勿变来变去
递归具有固有的局限性,如果二叉树的深度太大,那么递归代码可能会导致调用的栈溢出问题,其次递归代码太简单,面试官增加难度会要求你写非递归形式。
import java.util.LinkedList;
import java.util.List;
import java.util.Stack;
public class Solution {
//中序遍历非递归形式
public List<Integer> inorderTraversal(TreeNode root){
List<Integer> nodes = new LinkedList<>();
Stack<TreeNode> stack = new Stack<>();
TreeNode cur = root;
while (cur!=null||!stack.isEmpty()){
while(cur!=null){
stack.push(cur);
cur = cur.left;
}
cur = stack.pop();
nodes.add(cur.val);
cur = cur.right;
}
return nodes;
}
//前序遍历非递归形式
public List<Integer> preorderTraversal(TreeNode root){
List<Integer> result = new LinkedList<>();
Stack<TreeNode> stack = new Stack<>();
TreeNode cur = root;
while (cur!=null||!stack.isEmpty()){
while(cur!=null){
stack.push(cur);
result.add(cur.val);
cur = cur.left;
}
cur = stack.pop();
cur = cur.right;
}
return result;
}
//后序遍历非递归形式
public List<Integer> postorderTraversal(TreeNode root){
List<Integer> result = new LinkedList<>();
Stack<TreeNode> stack = new Stack<>();
TreeNode cur = root;
//pre就是遍历过的前一个节点,初始化为null,在准备遍历下一个节点之前,就把指向它当前遍历的节点。
//它的作用是方式再次遍历节点的右子树,如果节点的右子树已经遍历过了,pre就指向它的右子树的根节点,这样增加条件cur.right !=pr, //防止再次遍历右子树
TreeNode pre = null;
while (cur!=null||!stack.isEmpty()){
while (cur!=null){
stack.push(cur);
cur = cur.left;
}
cur = stack.peek();
if (cur.right!=null && cur.right !=pre){
cur = cur.right;
}else {
stack.pop();
result.add(cur.val);
pre = cur;
//遍历完这个节点将这个节点赋值为空,这样下一次遍历的就是它的父节点了,直接到这cur = stack.peek();
cur = null;
}
}
return result;
}
}