preOrder
循环访问并将左孩子入栈
遇到 p = null , 要出栈, 并访问右孩子
public static void preOrder(TreeNode p) {
Stack<TreeNode> stack = new Stack<>();
while (p != null || !stack.isEmpty()) {
while (p != null) {
visit(p);
stack.push(p);
p = p.left;
}
p = stack.pop();
p = p.right;
}
}
inOrder
改变 visit() 的位置, 放到 pop下面
public static void inOrder(TreeNode p) {
Stack<TreeNode> stack = new Stack<>();
while (p != null || !stack.isEmpty()) {
while (p != null) {
stack.push(p);
p = p.left;
}
p = stack.pop();
visit(p);
p = p.right;
}
}
postOrder
观察后序遍历顺序是, 左-右-根
先序遍历顺序是, 根-左-右
用栈逆序, 右-左-根
再改变左右顺序, 左-右-根
public static void postOrder(TreeNode p) {
Stack<TreeNode> stack = new Stack<>();
Stack<TreeNode> help = new Stack<>();
while (p != null || !stack.isEmpty()) {
while (p != null) {
help.push(p);
stack.push(p);
p = p.right;
}
p = stack.pop();
p = p.left;
}
while (!help.isEmpty()) {
visit(help.pop());
}
}
层序遍历
队列实现, 同时维护两个变量:
currSize 表示当前行的剩余节点
nextSize 表示下一行的节点数量
public static void levelOrder(TreeNode p) {
if (p == null) return;
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(p);
int currSize = 1;
int nextSize = 0;
while (!queue.isEmpty()) {
p = queue.poll();
visit(p);
currSize--;
if (p.left != null) {
queue.offer(p.left);
nextSize++;
}
if (p.right != null) {
queue.offer(p.right);
nextSize++;
}
if (currSize == 0) {
currSize = nextSize;
nextSize = 0;
System.out.println();
}
}
}