** 二叉树前序、中序、后序递归遍历比较简单,一般会考二叉树前序、中序、后序非递归遍历,这里介绍一种模版,基于栈、16行代码实现轻松搞定前序、中序、后序非递归遍历。**
1、前序遍历(leetcode 144)
前序遍历首先取父节点的值,再取左节点的值,最后取右节点的值,即中-左-右。所以非递归的主要流程如下:
(1)、先取父节点的值。
(2)、遍历左子树。
(3)、基于栈遍历右子树。
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> list=new ArrayList<>();
Stack<TreeNode> stack=new Stack<>();
while(root!=null||(!stack.empty())){
if(root!=null){
list.add(root.val);//步骤一,取根节点的值
stack.push(root);//把根节点放入栈中
root=root.left;//步骤二,遍历左子树
}
else{
TreeNode tem=stack.pop();
root=tem.right;//步骤三,遍历右子树
}
}
return list;
}
}
2、中序遍历(leetcode 94)
中序遍历首先取左节点的值,再取父节点的值,最后取右节点的值,即左-中-右。所以非递归的主要流程如下:
(1)、遍历左子树。
(2)、取父节点的值。
(3)、基于栈遍历右子树。
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> list=new ArrayList<>();
Stack<TreeNode> stack=new Stack<>();
while(root!=null||(!stack.empty())){
if(root!=null){
stack.push(root);
root=root.left;//步骤一,遍历左子树
}
else{
TreeNode tem=stack.pop();
list.add(tem.val);////步骤二,取根结点的值
root=tem.right;//步骤三,遍历右子树
}
}
return list;
}
}
3、后序遍历(leetcode 145)
后序遍历首先取左节点的值,再取右节点的值,最后取父节点的值,即左-右-中。这里采用一种倒序处理的办法,先处理成中-右-左,再对结果逆序处理就行,所以非递归的主要流程如下:
(1)、取父节点的值。
(2)、遍历右子树。
(3)、基于栈遍历左子树。
(4)、对结果逆序处理。
import java.util.Collections;
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
Stack<TreeNode> stack = new Stack<>();
List<Integer> result=new ArrayList<>();
while(root!=null||!stack.isEmpty()){
if(root!=null){
result.add(root.val);//取父节点的值
stack.add(root);
root=root.right;//遍历右子树
}else{
TreeNode tem=stack.pop();
root=tem.left;//遍历左子树
}
}
Collections.reverse(result);//对结果逆序处理
return result;
}
}
好了,16行代码模板轻松搞定了前序、中序、后序非递归遍历,赶紧去leetcode试试吧。