《艾爾登法環》女武神招式解析及打法心得 女武神怎麼打
阿新 • • 發佈:2022-03-08
二叉樹的前序遍歷
題目描述
給你二叉樹的根節點 root
,返回它節點值的 前序 遍歷。
示例 1:
輸入:root = [1,null,2,3]
輸出:[1,2,3]
示例 2:
輸入:root = []
輸出:[]
示例 3:
輸入:root = [1]
輸出:[1]
方法一:遞迴
對於樹的遍歷來說,遞迴的方法永遠是最簡單的。
前序遍歷:根->左子樹->右子樹。
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode() {} * TreeNode(int val) { this.val = val; } * TreeNode(int val, TreeNode left, TreeNode right) { * this.val = val; * this.left = left; * this.right = right; * } * } */ class Solution { public List<Integer> preorderTraversal(TreeNode root) { List<Integer> ans = new ArrayList<>(); preOrder(ans, root); return ans; } private void preOrder(List<Integer> ans, TreeNode root) { if (root!=null) { ans.add(root.val); preOrder(ans, root.left); preOrder(ans, root.right); } } }
方法二:迭代
我們也可以用迭代的方式實現方法一的遞迴函式,兩種方式是等價的,區別在於遞迴的時候隱式地維護了一個棧,而我們在迭代的時候需要顯式地將這個棧模擬出來,其餘的實現與細節都相同,具體可以參考下面的程式碼。
思路:針對二叉樹先序遍歷 根->左子樹->右子樹 的順序
- 對於每一個結點,我們一直遍歷到它的最左邊
- 然後返回上一個結點
- 再遍歷它的右邊。
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode() {} * TreeNode(int val) { this.val = val; } * TreeNode(int val, TreeNode left, TreeNode right) { * this.val = val; * this.left = left; * this.right = right; * } * } */ class Solution { public List<Integer> preorderTraversal(TreeNode root) { List<Integer> ans = new ArrayList<>(); Stack<TreeNode> stack = new Stack<>(); while (root!=null || !stack.isEmpty()) { while (root!=null) { ans.add(root.val); stack.add(root); root = root.left; } root = stack.pop(); root = root.right; } return ans; } }
方法三:Morris 遍歷
Morris
遍歷的核心思想是利用樹的大量空閒指標,實現空間開銷的極限縮減。其前序遍歷規則總結如下:
- 新建臨時節點,令該節點為
root
; - 如果當前節點的左子節點為空,將當前節點加入答案,並遍歷當前節點的右子節點;
- 如果當前節點的左子節點不為空,在當前節點的左子樹中找到當前節點在中序遍歷下的前驅節點:
- 如果前驅節點的右子節點為空,將前驅節點的右子節點設定為當前節點。然後將當前節點加入答案,並將前驅節點的右子節點更新為當前節點。當前節點更新為當前節點的左子節點。
- 如果前驅節點的右子節點為當前節點,將它的右子節點重新設為空。當前節點更新為當前節點的右子節點。
- 重複步驟 2 和步驟 3,直到遍歷結束。
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<Integer>();
if (root == null) {
return res;
}
TreeNode p1 = root, p2 = null;
while (p1 != null) {
p2 = p1.left;
if (p2 != null) {
while (p2.right != null && p2.right != p1) {
p2 = p2.right;
}
if (p2.right == null) {
res.add(p1.val);
p2.right = p1;
p1 = p1.left;
continue;
} else {
p2.right = null;
}
} else {
res.add(p1.val);
}
p1 = p1.right;
}
return res;
}
}