二叉树节点定义:
class Node {
public int val;
public Node left;
public Node right;
public Node(int val) {
this.val = val;
}
public static Node buildTree() {
Node root = new Node(1);
Node node1 = new Node(2);
Node node2 = new Node(3);
root.left = node1;
root.right = node2;
node1.left = new Node(4);
node1.right = new Node(5);
node2.left = new Node(6);
node2.right = new Node(7);
return root;
}
}
先序遍历:
public static void preOrder1(Node root) {
if (root == null)
return;
System.out.print(root.val + " ");
preOrder1(root.left);
preOrder1(root.right);
}
public static void preOrder2(Node node) {
if (node == null) {
return;
}
Stack<Node> stack = new Stack<>();
while (node != null || !stack.isEmpty()) {
while (node != null) {// 一路向左
System.out.print(node.val + " ");
stack.push(node);
node = node.left;
}
//此处可以理解为递归遍地右子树
node = stack.pop().right;
}
}
public static void preOrder3(Node node) {
Stack<Node> s = new Stack<>();
while (node != null || !s.isEmpty()) {
if (node != null) {
System.out.print(node.val + " ");
node = node.left;
} else {
node = s.pop();
s.push(node);
}
}
}
中序遍历:
/**
* 跟前序遍历很相似,就是打印节点值的位置不同
* @param node
*/
public static void inOrder(Node node) {
Stack<Node> s = new Stack<>();
while (node != null || !s.isEmpty()) {
while (node != null) {
s.push(node);
node = node.left;
}
node = s.pop();
System.out.print(node.val + " ");
node = node.right;
}
}
后序遍历:
package bintree;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import java.util.Stack;
class Node {
public int val;
public Node left;
public Node right;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Node node = (Node) o;
return val == node.val &&
Objects.equals(left, node.left) &&
Objects.equals(right, node.right);
}
@Override
public int hashCode() {
return Objects.hash(val, left, right);
}
public Node(int val) {
this.val = val;
}
public static Node buildTree() {
Node root = new Node(1);
Node node1 = new Node(2);
Node node2 = new Node(3);
root.left = node1;
root.right = node2;
node1.left = new Node(4);
node1.right = new Node(5);
node2.left = new Node(6);
node2.right = new Node(7);
return root;
}
}
public class Main {
public static void main(String[] args) {
Node node = Node.buildTree();
post(node);
System.out.println();
postTree(node);
}
public static void postTree(Node node) {
if (Objects.isNull(node)) {
return;
}
// 用于回溯的栈
Stack<Node> stack = new Stack<>();
// 用于存储已经遍历过的节点
Set<Node> visited = new HashSet<>();//重写Node hashcode与equals方法
stack.push(node);
// 后序遍历打印节点的值都是打印的栈中的,因此只要判断栈不空则就是没有遍历结束
while (!stack.isEmpty()) {
node = stack.peek();
// 当前节点的左节点不空而且该节点没有被遍历过
while (Objects.nonNull(node.left) && !visited.contains(node.left)) {
//存储到栈中,继续向下走
stack.push(node.left);
node = node.left;
}
// 此时已经走到了最左边了,开始回溯一个节点向右子树走
node = stack.peek();
// 右节点不空而且没有遍历过则添加到队列中
if (Objects.nonNull(node.right) && !visited.contains(node.right)) {
node = stack.peek().right;
stack.push(node);
// 此时可以将右节点看做一颗子树,从新开始以后序遍历的方式遍历该子树
continue;
}
//左右子树为空或者左右子树已经遍历完毕
node = stack.pop();
visited.add(node);
System.out.print(node.val + " ");
}
}
public static void post(Node node) {
if (Objects.isNull(node)) {
return;
}
post(node.left);
post(node.right);
System.out.print(node.val + " ");
}
}