推荐两个up主:
happygirlzt
图灵星球Turing Planet及其个人网站
本博文参考的视频:
二叉树前序中序后序遍历(深度优先搜索)的迭代解法
本博文参考的文章:
数据结构图文解析之:栈的简介及C++模板实现
动画演示+三种实现 94. 二叉树的中序遍历
栈的相关概念
栈顶与栈底:允许元素插入与删除的一端称为栈顶,另一端称为栈底。
压栈:栈的插入操作,叫做进栈,也称压栈、入栈。
弹栈:栈的删除操作,也叫做出栈。
压栈的过程中,栈顶的位置一直在“向上”移动,而栈底是固定不变的。
出栈的过程中,栈顶的位置一直在“向下”移动,而栈底是固定不变的。
先进后出原则
压栈顺序:1—>2—>3
出栈顺序:3—>2—>1
前序遍历(pre-order)
先打印root节点,再打印left节点,最后打印right节点。
输出为:F B A D C E G I H
递归(recursion)
1 2 3 4 5 6 7 8 9 10
| class Solution { List<Integer> res = new ArrayList<>(); public List<Integer> preorderTraversal(TreeNode root) { if(root == null) return res; res.add(root.val); preorderTraversal(root.left); preorderTraversal(root.right); return res; } }
|
辅助栈
原则:right先入栈,left后入栈(先打印left,后打印right)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| class Solution { public List<Integer> preorderTraversal(TreeNode root) { List<Integer> res = new ArrayList<>(); if(root == null) return res;
Deque<TreeNode> stack = new ArrayDeque<>(); stack.push(root);
while(!stack.isEmpty()){ TreeNode node = stack.pop(); res.add(node.val);
if(node.right != null){ stack.push(node.right); }
if(node.left != null){ stack.push(node.left); } } return res; } }
|
中序遍历(in-order)
先打印left节点,再打印root节点,最后打印right节点。
输出为:A B C D E F G H I
递归(recursion)
1 2 3 4 5 6 7 8 9 10
| class Solution { List<Integer> res = new ArrayList<>(); public List<Integer> inorderTraversal(TreeNode root) { if(root == null) return res; inorderTraversal(root.left); res.add(root.val); inorderTraversal(root.right); return res; } }
|
辅助栈
动图来源:动画演示+三种实现 94. 二叉树的中序遍历
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| class Solution { public List<Integer> inorderTraversal(TreeNode root) { List<Integer> res = new ArrayList<>(); if(root == null) return res; Deque<TreeNode> stack = new ArrayDeque<>(); while(!stack.isEmpty() || root != null){ while(root != null){ stack.push(root); root = root.left; } TreeNode tmp = stack.pop(); res.add(tmp.val); root = tmp.right; } return res; } }
|
后序遍历(post-order)
先打印left节点,再打印right节点,最后打印root节点。
输出为:A C E D B H I G F
递归(recursion)
1 2 3 4 5 6 7 8 9 10 11
| class Solution { List<Integer> res = new ArrayList<>(); public List<Integer> postorderTraversal(TreeNode root) { if(root == null) return res; postorderTraversal(root.left); postorderTraversal(root.right); res.add(root.val); return res;
} }
|
辅助栈
后序遍历利用辅助栈的方式和前序遍历类似
前序遍历要求:root—>left—>right
后序遍历要求:left—>right—root
可以理解为先将先序遍历的left和right顺序互换,然后整体反转,得到后序遍历结果。
因此left先进栈,right后进栈。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| class Solution { public List<Integer> postorderTraversal(TreeNode root) { LinkedList<Integer> res = new LinkedList<>(); if(root == null) return res;
Deque<TreeNode> stack = new ArrayDeque<>(); stack.push(root);
while(!stack.isEmpty()){ TreeNode node = stack.pop(); res.addFirst(node.val);
if(node.left != null){ stack.push(node.left); }
if(node.right != null){ stack.push(node.right); } } return res;
} }
|