二叉树的前序遍历、二叉树的中序遍历、二叉树的后序遍历
递归实现:
前序遍历
class Solution {
List<Integer> list = new ArrayList<>();
public List<Integer> preorderTraversal(TreeNode root) {
if(root!=null)
{
list.add(root.val);
preorderTraversal(root.left);
preorderTraversal(root.right);
}
return list;
}
}
边界判断:空节点返回空列表
中序遍历
class Solution {
List<Integer> list = new ArrayList<>();
public List<Integer> inorderTraversal(TreeNode root) {
if(root!=null)
{
inorderTraversal(root.left);
list.add(root.val);
inorderTraversal(root.right);
}
return list;
}
}
后序遍历
class Solution {
List<Integer> list = new ArrayList<>();
public List<Integer> postorderTraversal(TreeNode root) {
if(root!=null)
{
postorderTraversal(root.left);
postorderTraversal(root.right);
list.add(root.val);
}
return list;
}
}
迭代实现:
前序遍历
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList();
if(root!=null)
{
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while(!stack.isEmpty())
{
TreeNode node=stack.pop();
list.add(node.val);
if(node.right!=null)
{
stack.push(node.right);
}
if(node.left!=null)
{
stack.push(node.left);
}
}
}
return list;
}
}
本质:使用辅助栈模拟递归栈
迭代实现:
中序遍历
中序遍历的迭代实现和前序遍历类似,也是借助一个辅助栈,根据中序遍历的顺序 【根-左-右】
1、递归遍历树左节点入栈
2、判断栈顶节点是否存在右节点,存在则继续1
tip:先想好做什么,最后再把外层循环和终止条件套上
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
TreeNode cur=root;
while(!stack.isEmpty()||root!=null)
{
while(root!=null)
{
stack.push(root);
root=root.left;
}
cur=stack.pop();
list.add(cur.val);
if(cur.right!=null)
{
root=cur.right;
}
}
return list;
}
}
迭代实现:
后序遍历
二叉树的后序遍历迭代实现比较难。
方式一:根据后序遍历 左-右-根的顺序 先遍历左子树,依次入栈,出栈时判断右子树是否存在,存在则节点重新入栈,对右子树进行同样的操作。
难点:节点存在右子树,但是已经遍历过,无须再入栈
初步代码:
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
TreeNode pre=null;
while(root!=null || !stack.isEmpty())
{
while(root!=null)
{
stack.add(root);
root=root.left;
}
root=stack.pop();
if(root.right==null)
{
list.add(root.val);
root=null;//防止死循环
}
else
{
stack.push(root);
root=root.right;
}
}
return list;
}
}
二次代码
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
TreeNode pre=null;
while(root!=null || !stack.isEmpty())
{
while(root!=null)
{
stack.add(root);
root=root.left;
}
root=stack.pop();
//增加一个pre指针表示当前节点的右节点已入过栈,无须再次入栈
if(root.right==null||pre==root.right)
{
list.add(root.val);
pre=root;
root=null;
}
else
{
stack.push(root);
root=root.right;
}
}
return list;
}
}
不管是递归还是迭代 ,时间和空间都是复杂度为O(N)