二叉樹遍歷小結
聲明
文章均爲本人技術筆記,轉載請註明出處:
[1] https://segmentfault.com/u/yzwall
[2] blog.csdn.net/j_dark/
0 二叉樹遍歷概述
二叉樹遍歷:按照既定序,對每個節點僅訪問一次;
二叉樹非遞歸遍歷思想:參考這篇博文,核心思想是存在重合元素的局部有序保證整體有序,由於二叉樹的結構特點,二叉樹中的每個節點(除根節點和葉子節點)均屬於兩個局部的重合元素。對於任一重合元素,保證所在兩個局部遍歷有序,保證實現整體遍歷有序;
- 重合元素所在局部:
- 局部全部有序,遍歷該元素並出棧;
- 局部未全部有序,將未有序局部元素全部入棧。由於棧是LIFO,局部元素按照逆序入棧;
二叉樹節點TreeNode
聲明
public class TreeNode {
public int val;
public TreeNode left, right;
public TreeNode(int val) {
this.val = val;
this.left = this.right = null;
}
}
1 前序遍歷
1.1 非遞歸實現
public class Solution {
private class Pair {
public TreeNode node;
public boolean isVisited;
public Pair(TreeNode node, boolean isVisited) {
this.node = node;
this.isVisited = isVisited;
}
}
public ArrayList<Integer> preorderTraversal(TreeNode root) {
ArrayList<Integer> list = new ArrayList<Integer>();
if (root == null) {
return list;
}
ArrayDeque<Pair> stack = new ArrayDeque<Pair>();
stack.push(new Pair(root, false));
while (!stack.isEmpty()) {
Pair top = stack.pop();
// 重合節點完成所有局部有序,彈出
if (top.isVisited) {
list.add(top.node.val);
} else {
// reverse: right -> left -> root
if (top.node.right != null) {
stack.push(new Pair(top.node.right, false));
}
if (top.node.left != null) {
stack.push(new Pair(top.node.left, false));
}
stack.push(new Pair(top.node, true));
}
}
return list;
}
}
1.2 遞歸實現
public class Solution {
public ArrayList<Integer> preorderTraversal(TreeNode root) {
ArrayList<Integer> list = new ArrayList<Integer>();
if (root == null) {
return list;
}
traverse(list, root);
return list;
}
private void traverse(ArrayList<Integer>list, TreeNode root) {
if (root == null) {
return;
}
list.add(root.val);
traverse(list, root.left);
traverse(list, root.right);
}
}
2 中序遍歷
2.1 非遞歸實現
public class Solution {
private class Pair {
public TreeNode node;
public boolean isVisited;
public Pair(TreeNode node, boolean isVisited) {
this.node = node;
this.isVisited = isVisited;
}
}
public ArrayList<Integer> inorderTraversal(TreeNode root) {
ArrayList<Integer> list = new ArrayList<Integer>();
if (root == null) {
return list;
}
ArrayDeque<Pair> stack = new ArrayDeque<Pair>();
stack.push(new Pair(root, false));
while (!stack.isEmpty()) {
Pair top = stack.pop();
if (top.isVisited) {
list.add(top.node.val);
} else {
// reverse: right -> root -> left
if (top.node.right != null) {
stack.push(new Pair(top.node.right, false));
}
stack.push(new Pair(top.node, true));
if (top.node.left != null) {
stack.push(new Pair(top.node.left, false));
}
}
}
return list;
}
}
2.2 遞歸實現
public class Solution {
public ArrayList<Integer> inorderTraversal(TreeNode root) {
ArrayList<Integer> list = new ArrayList<Integer>();
if (root == null) {
return list;
}
traverse(list, root);
return list;
}
private void traverse(ArrayList<Integer>list, TreeNode root) {
if (root == null) {
return;
}
traverse(list, root.left);
list.add(root.val);
traverse(list, root.right);
}
}
3 後序遍歷
3.1 非遞歸實現
public class Solution {
private class Pair {
public TreeNode node;
public boolean isVisited;
public Pair(TreeNode node, boolean isVisited) {
this.node = node;
this.isVisited = isVisited;
}
}
public ArrayList<Integer> postorderTraversal(TreeNode root) {
ArrayList<Integer> list = new ArrayList<Integer>();
if (root == null) {
return list;
}
ArrayDeque<Pair> stack = new ArrayDeque<Pair>();
stack.push(new Pair(root, false));
while (!stack.isEmpty()) {
Pair top = stack.pop();
if (top.isVisited) {
list.add(top.node.val);
} else {
// reverse: root -> right -> left
stack.push(new Pair(top.node, true));
if (top.node.right != null) {
stack.push(new Pair(top.node.right, false));
}
if (top.node.left != null) {
stack.push(new Pair(top.node.left, false));
}
}
}
return list;
}
}
3.2 遞歸實現
public class Solution {
public ArrayList<Integer> postorderTraversal(TreeNode root) {
ArrayList<Integer> list = new ArrayList<Integer>();
if (root == null) {
return list;
}
traverse(list, root);
return list;
}
private void traverse(ArrayList<Integer> list, TreeNode root) {
if (root == null) {
return;
}
traverse(list, root.left);
traverse(list, root.right);
list.add(root.val);
}
}
4 層序遍歷
- lintcode 二叉樹的層序遍歷,BFS按層遍歷實現
public class Solution {
public ArrayList<ArrayList<Integer>> levelOrder(TreeNode root) {
ArrayDeque<TreeNode> queue = new ArrayDeque<TreeNode>();
ArrayList<ArrayList<Integer>> list = new ArrayList<ArrayList<Integer>>();
if (root == null) {
return list;
}
queue.offer(root);
while (!queue.isEmpty()) {
int level = queue.size();
ArrayList<Integer> levelList = new ArrayList<Integer>();
// 按層BFS遍歷
for (int i = 0; i < level; i++) {
TreeNode head = queue.poll();
levelList.add(head.val);
if (head.left != null) {
queue.offer(head.left);
}
if (head.right != null) {
queue.offer(head.right);
}
}
list.add(levelList);
}
return list;
}
}