先序遍历:先遍历当前节点,再遍历当前节点的左孩子,在遍历当前节点的有孩子
把打印的时机放到第几次遍历这个节点,对应不同的遍历
当第一次来到这个节点的时候,对应先序遍历
当第二次来到这个节点的时候,对应中序遍历
当第三次来到这个节点的时候,对应后续遍历
递归版
/先序遍历
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) {
System.out.print("pre-order: ");
if (head != null) {
Stack<Node> stack = new Stack<Node>();
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);
}
}
}
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;
}
}
}
System.out.println();
}
后续遍历:由于后续遍历是第三次来到节点,但是栈只能两次访问节点,因此另辟蹊径
首先根据先序遍历,很容易实现的是 当前节点,右子树,左子树的遍历顺序,因此新建一个栈,保存另一个栈中弹出的结点,访问结束后进行打印,因此可以得到先左子树,再右子树,最后根节点的遍历顺序。
public static void posOrderUnRecur1(Node head) {
System.out.print("pos-order: ");
if (head != null) {
Stack<Node> s1 = new Stack<Node>();
Stack<Node> s2 = new Stack<Node>();
s1.push(head);
while (!s1.isEmpty()) {
head = s1.pop();
s2.push(head);
if (head.left != null) {
s1.push(head.left);
}
if (head.right != null) {
s1.push(head.right);
}
}
while (!s2.isEmpty()) {
System.out.print(s2.pop().value + " ");
}
}
System.out.println();
}