题目 实现二叉树的先序、中序、后序遍历,包括递归方式和非递归方式。
思路 递归:过于简单,不需要表述。
非递归:(1)先序遍历【根左右】,设置一个辅助栈,先将根节点放到栈中。栈非空时,遍历剩余部分。遍历时,先弹出栈顶元素,输出,并判断该元素的右孩子节点是否为空,若非空则压入栈中;再判断左孩子节点是否为空,若非空则压入栈中。
(2)中序遍历【左根右】,设置一个辅助栈,当栈非空或者当前节点(起始为根节点)非空时,开始遍历。遍历时先判断当前节点左孩子节点是否为空,若非空则将左孩子节点压入栈中,并将左孩子节点设为当前节点;再判断栈是否为空,若非空则将栈顶元素赋值给当前节点,弹出栈顶元素并输出,并将当前节点的右孩子节点设为当前节点。
(3)后序遍历【左右根】①:设置两个辅助栈stack1,stack2。利用先序遍历实现后序遍历。因为先序遍历顺序为根左右,将左右互换位置并逆序,得到左右根,即为后序遍历。所以类似于先序遍历(需要的顺序是根右左),先将根节点放到stack1中,若stack1非空,则进行下面的遍历,先弹出stack1的栈顶元素,并将其压入stack2中。接下来判断当前节点的左孩子是否为空,若非空则将其入stack1栈;再判断当前节点的有孩子是否为空,若非空则将其入stack1栈。遍历完成后,依次弹出stack2中的元素,便可以得到后序遍历结果。
(4)后序遍历【左右根】②:设置一个辅助栈,先将根节点放到栈中。设置一个辅助指针。栈非空时开始遍历。遍历时,辅助指针先指向栈顶元素,然后开始判断辅助指针指向的节点的左孩子是否为空,同时判断辅助指针指向节点的左孩子和右孩子是否等于当前节点(head),若左孩子不为空,且左孩子和右孩子不等于当前节点,则将左孩子压入栈中;再判断辅助指针指向节点的左孩子是否等于当前节点,同时判断辅助指针指向节点的右孩子是否为空,若右孩子不为空,且左孩子不等于当前节点,则将有孩子压入栈中;否则将辅助指针指向的元素,即栈顶元素,赋给当前节点,并弹出栈顶元素,输出。
package algorithm.section5;
import java.util.Stack;
public class PreInPosTraversal {
public static class Node{
public int value;
public Node left;
public Node right;
public Node(int value){
this.value = value;
}
}
public static void preOrderRecur(Node head){
if (head == null) return;
System.out.print(head.value + " ");
preOrderRecur(head.left);
preOrderRecur(head.right);
}
public static void inOrderRecur(Node head){
if (head == null) return;
inOrderRecur(head.left);
System.out.print(head.value + " ");
inOrderRecur(head.right);
}
public static void posOrderRecur(Node head){
if (head == null) return;
posOrderRecur(head.left);
posOrderRecur(head.right);
System.out.print(head.value + " ");
}
public static void preOrderUnRecur(Node head){
if (head == null) return;
Stack<Node> stack = new Stack<>();
stack.push(head);
while (!stack.isEmpty()){
head = stack.pop();
System.out.print(head.value + " ");
if (head.right != null)
stack.push(head.right);
if (head.left != null)
stack.push(head.left);
}
}
public static void inOrderUnRecur(Node head){
if (head == null) return;
Stack<Node> stack = new Stack<>();
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;
}
}
}
public static void posOrderUnRecur1(Node head){
if (head == null) return;
Stack<Node> stack1 = new Stack<>();
Stack<Node> stack2 = new Stack<>();
stack1.push(head);
while (!stack1.isEmpty()){
head = stack1.pop();
stack2.push(head);
if (head.left != null)
stack1.push(head.left);
if (head.right != null)
stack1.push(head.right);
}
while (!stack2.isEmpty())
System.out.print(stack2.pop().value + " ");
}
public static void posOrderUnRecur2(Node head){
if (head == null) return;
Stack<Node> stack = new Stack<>();
stack.push(head);
Node flag;
while (!stack.isEmpty()){
flag = stack.peek();
if (flag.left != null && head != flag.right && head != flag.left){
stack.push(flag.left);
} else if (head != flag.right && flag.right != null){
stack.push(flag.right);
} else {
head = flag;
System.out.print(flag.value + " ");
stack.pop();
}
}
}
public static void main(String[] args){
Node head = new Node(5);
head.left = new Node(3);
head.right = new Node(8);
head.left.left = new Node(2);
head.left.right = new Node(4);
head.left.left.left = new Node(1);
head.right.left = new Node(7);
head.right.left.left = new Node(6);
head.right.right = new Node(10);
head.right.right.left = new Node(9);
head.right.right.right = new Node(11);
System.out.println("==============recursive==============");
System.out.print("pre-order: ");
preOrderRecur(head);
System.out.println();
System.out.print("in-order: ");
inOrderRecur(head);
System.out.println();
System.out.print("pos-order: ");
posOrderRecur(head);
System.out.println();
// unrecursive
System.out.println("============unrecursive=============");
preOrderUnRecur(head);
System.out.println();
inOrderUnRecur(head);
System.out.println();
posOrderUnRecur1(head);
System.out.println();
posOrderUnRecur2(head);
}
}