JAVA二刷-Day14 | 144.二叉树的前序遍历, 145.二叉树的后序遍历, 94.二叉树的中序遍历
迭代方法由于要满足弹出时候的左中右或者中左右或者左右中顺序。
二叉树的前序遍历
LeetCode题目链接:https://leetcode.cn/problems/binary-tree-preorder-traversal/
解题思路
递归方法代码,迭代的方法都比较相同:
class Solution {
public void preOrder(TreeNode root, List<Integer> result) {
if (root == null) return;
result.add(root.val);
preOrder(root.left, result);
preOrder(root.right, result);
return;
}
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
preOrder(root, result);
return result;
}
}
迭代方法代码:
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
Stack<TreeNode> stkNode = new Stack<TreeNode>();
stkNode.push(root);
while (!stkNode.isEmpty()) {
TreeNode node = stkNode.peek();
stkNode.pop();
if (node != null) {
result.add(node.val);
if (node.right != null) stkNode.push(node.right);
if (node.left != null) stkNode.push(node.left);
}
}
return result;
}
}
二叉树的后序遍历
LeetCode题目链接:https://leetcode.cn/problems/top-k-frequent-elements/
解题思路
递归方法与前序类似,迭代方法也可以简单修改顺序和翻转后完成。
具体代码如下:
class Solution {
public void postOrder(TreeNode root, List<Integer> result) {
if (root == null) return;
postOrder(root.left, result);
postOrder(root.right, result);
result.add(root.val);
return;
}
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
postOrder(root, result);
return result;
}
}
二叉树的中序遍历
LeetCode题目链接:https://leetcode.cn/problems/binary-tree-inorder-traversal/
解题思路
递归方法与前序相同,迭代方法需要注意中序的特殊性质,即元素入栈顺序和实际加载顺序不相关,因此需要特殊处理。
具体代码如下:
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
Stack<TreeNode> stkNode = new Stack<TreeNode>();
TreeNode current = root;
while (current != null || !stkNode.isEmpty()) {
if (current != null) {
stkNode.add(current);
current = current.left;
}else {
current = stkNode.peek();
stkNode.pop();
result.add(current.val);
current = current.right;
}
}
return result;
}
}
统一迭代法
统一迭代法主要的思想是对要取出的元素后加入NULL标记来进行迭代。如果迭代到某个根元素的时候没有NULL标记,可以理解为该点元素还没有被拿出来查询分支过,以此来进行不断的迭代循环,经过查询后的节点才可以放入返回数组中。
以下是前序遍历的标记迭代法,进行中序后序遍历,只需要改变cur和NULL 的位置即可,因为cur被理解为被查询分支的那个节点,所以对他进行标记而不是对该节点的两个分支进行标记:
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
Stack<TreeNode> stkNode = new Stack<TreeNode>();
if (root != null) stkNode.push(root);
while (!stkNode.isEmpty()) {
TreeNode cur = stkNode.peek();
if (cur != null) {
stkNode.pop();
if (cur.right != null) stkNode.add(cur.right);
if (cur.left != null) stkNode.add(cur.left);
stkNode.add(cur);
stkNode.add(null);
}else {
stkNode.pop();
cur = stkNode.peek();
stkNode.pop();
result.add(cur.val);
}
}
return result;
}
}