先序遍历
例题: https://leetcode-cn.com/problems/binary-tree-preorder-traversal/
1 2 3 4 5 6 7 8
| public void traversal(TreeNode root) { if(root == null){ return; } System.out.println(root.val); traversal(root.left); traversal(root.right); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public void traversal(TreeNode root){ if(root == null){ return; } Deque<TreeNode> stack = new LinkedList<>(); while(root != null || !stack.isEmpty()){ while(root != null){ System.out.println(root.val); stack.push(root); root = root.left; } root = stack.pop(); root = root.right; } }
|
利用栈通过类似于层序遍历的方法实现先序遍历,也算是一种迭代
思路: 若树不为空,先将根结点入栈。之后在循环内删除并得到栈顶结点,输出其值后依次将右、左儿子入栈。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public void traversal(TreeNode root){ if(root == null){ return; } Deque<TreeNode> stack = new LinkedList<>(); stack.push(root); while(!stack.isEmpty()){ root = stack.pop(); System.out.println(root.val); if(root.right != null){ stack.push(root.right); } if(root.left != null){ stack.push(root.left); } } }
|
中序遍历
例题: https://leetcode-cn.com/problems/binary-tree-inorder-traversal/
1 2 3 4 5 6 7 8
| public void traversal(TreeNode root) { if(root == null){ return; } traversal(root.left); System.out.println(root.val); traversal(root.right); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public void traversal(TreeNode root){ if(root == null){ return; } Deque<TreeNode> stack = new LinkedList<>(); while(root != null || !stack.isEmpty()){ while(root != null){ stack.push(root); root = root.left; } root = stack.pop(); System.out.println(root.val); root = root.right; } }
|
后序遍历
例题: https://leetcode-cn.com/problems/binary-tree-postorder-traversal/
1 2 3 4 5 6 7 8 9
| public void traversal(TreeNode root) { if(root == null){ return; } traversal(root.left); traversal(root.right); System.out.println(root.val);
}
|
相比先序和中序更复杂一点,因为是先遍历左、右子树再输出根结点,所以可能需要二次入栈。
思路: 用一个指针pre 来储存上一次遍历过的右孩子,防止回到根结点后再次遍历该右孩子。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| public void traversal(TreeNode root){ if(root != null){ return; } Deque<TreeNode> stack = new LinkedList<>(); TreeNode pre = null; while(root != null || !stack.isEmpty()){ while(root != null){ stack.push(root); root = root.left; } root = stack.pop(); if(root.right != null && root.right != pre){ stack.push(root); root = root.right; }else{ System.out.println(root.val); pre = root; root = null; } } }
|
思路: 将先序遍历的左孩子和右孩子操作调换,得到逆后序 根、右、左。再将结果依次入到辅助栈中,利用栈先入后出的顺序,反转逆后序得到 左、右、根 后序输出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public void traversal(TreeNode root){ if(root == null){ return; } Deque<TreeNode> stack = new LinkedList<>(); Deque<Integer> helpStack = new LinkedList<>(); while(root != null || !stack.isEmpty()){ while(root != null){ helpStack.push(root.val); stack.push(root); root = root.right; } root = stack.pop(); root = root.left; } while(!helpStack.isEmpty()){ System.out.println(helpStack.pop()); } }
|
结合先序迭代2方法和后序迭代2方法同样可以实现可以实现
先用先序迭代2方法实现逆后序,再用后序迭代2方法实现反转逆后序得到后序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| public void traversal(TreeNode root){ if(root == null){ return; } Deque<TreeNode> stack = new LinkedList<>(); Deque<Integer> helpStack = new LinkedList<>(); stack.push(root); while(!stack.isEmpty()){ root = stack.pop(); helpStack.push(root.val); if(root.left != null){ stack.push(root.right); } if(root.right != null){ stack.push(root.left); } } while(!helpStack.isEmpty()){ System.out.println(helpStack.pop()); } }
|
层序遍历
例题: https://leetcode-cn.com/problems/binary-tree-level-order-traversal/
- 层序遍历的实现需要利用到队列。
- 层序遍历是从上至下,从左至右遍历输出的。
- 具体步骤为:根结点入队 -> while{出队 -> 输出 -> 左右孩子入队}
例如:[A],[BC],[EFGH],[IZ]
通过获取当前队列的大小,再根据大小设置循环,循环内输出同一层的结点值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| public void traversal(TreeNode root){ if(root == null){ return; } Deque<TreeNode> queue = new ArrayDeque<>(); queue.offer(root); while(!queue.isEmpty()){ int size = queue.size(); List<Integer> list = new ArrayList<>(); for(int i = 0; i < size; i++){ root = queue.poll(); list.add(root.val); if(root.left != null){ queue.offer(root.left); } if(root.right != null){ queue.offer(root.right); } } System.out.println(list); } }
|
例如:A,B,C,D,E,F,G,H,I,Z
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public void traversal(TreeNode root){ if(root == null){ return; } Deque<TreeNode> queue = new ArrayDeque<>(); queue.offer(root); while(!queue.isEmpty()){ root = queue.poll(); System.out.println(root.val); if(root.left != null){ queue.offer(root.left); } if(root.right != null){ queue.offer(root.right); } } }
|