用递归和非递归俩种方式实现二叉树的 先序遍历 中序遍历 后序遍历
1. 递归序
public static void f(Node head) {
// 1
if (head == null) {
return;
}
// 1
f(head.left);
// 2
// 2
f(head.right);
// 3
// 3
}
1,2,4,4,4,2,5,2,1,3,6,6,6,3,7,7,7,3,1
递归序每个节点都会回到3次
在递归序可以加工出 先序 中序 后序
先序遍历
对于所有子树上,都是先打印 头结点 在打印 左节点 再打印 右节点
1,2,4,5,3,6,7
递归序中只有第一次打印,就是先序遍历
中序遍历(左头右)
4,2,5,1,6,3,7
递归序中在第二次才打印,就是中序遍历
后序遍历(左右头)
4,5,2,6,7,3,1
递归序中在最后一次才打印,就是后序遍历
2. 非递归如何实现
先序遍历(头左右) 1,2,4,5,3,6,7
准备一个栈 1 先把头节点放到栈里 2 每次在栈中弹出一个节点 记为cur 弹出并打印 3 先右后左(如果有) 4 重复
public static void preOrderUnRecur(Node head) {
System.out.print("pre-order: ");
// 如果头节点不等于空
if (head != null) {
// 准备一个栈
Stack<Node> stack = new Statck<Node>();
// 1 先把头节点放到栈里
stack.add(head);
while(!stack.isEmpty()) {
// 2 每次在栈中弹出一个节点 记为cur 弹出并打印
head = stack.pop();
System.out.print(head.value + " ");
// 3 先右后左(如果有)
if (head.right != null) {
stack.push(head.right);
}
if (head.left != null) {
stack.push(head.left);
}
}
}
System.out.println();
}
后序遍历
由先序遍历 头左右 改为 头右左 然后放到收集栈里,再打印收集栈里的(左右头)即为后序遍历
public static void preOrderUnRecur(Node head) {
System.out.print("after-order: ");
// 如果头节点不等于空
if (head != null) {
// 准备一个栈
Stack<Node> stack = new Statck<Node>();
Stack<Node> stack_temp = new Statck<Node>();
// 1 先把头节点放到栈里
stack.add(head);
while(!stack.isEmpty()) {
// 2 每次在栈中弹出一个节点 记为cur 弹出并打印
head = stack.pop();
stack_temp.push(head.value);
// 3 先左后右(如果有)
if (head.left != null) {
stack.push(head.left);
stack_temp.push(head.left);
}
if (head.right != null) {
stack.push(head.right);
stack_temp.push(head.right);
}
}
while(!stack.isEmpty()) {
System.out.print(stack_temp.pop() + " ");
}
}
System.out.println();
}
中序遍历(左头右)
先左边界全压,然后有右压右 重复弹出
public static void inOrderUnRecur(Node head) {
System.out.print("in-order: ");
if (head != null) {
Stack<Node> stack = new Stack<Node>();
while(!stack.isEmpty() || head != null) {
if (head != null) {
stack.push(head);
head = head.left;
} else {
head = stack.pop();
System.out.print(head.value + " ");
head = head.right;
}
}
}
}