1. 程式人生 > 其它 >Mako 模板用法

Mako 模板用法

程式碼隨想錄二叉樹專題,開刷!

先中後序遍歷的遞迴和迭代實現。

遞迴實現三種遍歷程式碼大致相同,只需要將遍歷左中右結點的程式碼換一下位置即可。

先序:

 1 class Solution {
 2     public List<Integer> preorderTraversal(TreeNode root) {
 3         List<Integer> res = new ArrayList<>();
 4         preOrder(root, res);
 5         return res;
 6     }
 7 
 8     public void preOrder(TreeNode root, List<Integer> res) {
 9         if (root == null) {
10             return;
11         }
12         res.add(root.val);
13         preOrder(root.left, res);
14         preOrder(root.right, res);
15     }
16 }

迭代實現就是定義一個棧來模擬遞迴過程。

先序:

 1 class Solution {
 2     public List<Integer> preorderTraversal(TreeNode root) {
 3         List<Integer> res = new ArrayList<>();
 4         Deque<TreeNode> stack = new LinkedList<>();
 5         stack.push(root);
 6         while (!stack.isEmpty()) {
 7             TreeNode cur = stack.pop();
 8             if (cur != null) {
 9                 //遍歷中結點,值放入結果集
10                 res.add(cur.val);
11                 //先放入右結點,再放入左結點,出棧就是先左後右
12                 stack.push(cur.right);
13                 stack.push(cur.left);
14             }
15         }
16         return res;
17     }
18 }

後序,按先序遍歷的來寫,結點入棧時先入右結點,再入左結點,得到的結果集就是中右左,然後reverse一下,就是我們需要的左右中遍歷結果了。

 1 class Solution {
 2     public List<Integer> postorderTraversal(TreeNode root) {
 3         List<Integer> res = new ArrayList<>();
 4         Deque<TreeNode> stack = new LinkedList<>();
 5         stack.push(root);
 6         while (!stack.isEmpty()) {
 7             TreeNode cur = stack.pop();
 8             if (cur != null) {
 9                 res.add(cur.val);
10                 stack.push(cur.left);
11                 stack.push(cur.right);
12             }
13         }
14         Collections.reverse(res);
15         return res;
16     }
17 }

中序遍歷結點和處理結點不能同時進行,此時不需要專門定義一個指標儲存根節點,左子樹遍歷完或左子樹為空時,遍歷根節點(根節點出棧),將右子樹根節點壓入棧中繼續遍歷。

 1 class Solution {
 2     public List<Integer> inorderTraversal(TreeNode root) {
 3         List<Integer> res = new ArrayList<>();
 4         Deque<TreeNode> stack = new LinkedList<>();
 5         stack.push(root);
 6         while (!stack.isEmpty()) {
 7             TreeNode cur = stack.peek();
 8             //遍歷左子樹
 9             //所有左子節點入棧,並找到當前結點的最左子節點
10             while (!stack.isEmpty() && cur != null) {
11                     stack.push(cur.left);
12                     cur = cur.left;
13             }
14             //空指標退棧
15             stack.pop();
16             //遍歷, 有左結點就遍歷左子節點,無左結點即null則在上一步退棧,此時遍歷的是當前節點。
17             if (!stack.isEmpty()) {
18                 cur = stack.pop();
19                 res.add(cur.val);
20                 stack.push(cur.right);
21             }
22         }
23         return res;
24     }
25 }

簡單題好像對我來說也不是很簡單。

參考:程式碼隨想錄:programmercarl.com、 資料結構(嚴蔚敏)