前序遍历: 先输出父节点,再遍历左子树和右子树
中序遍历: 先遍历左子树,再输出父节点,再遍历右子树
后序遍历: 先遍历左子树,再遍历右子树,最后输出父节点
小结: 看输出父节点的顺序,就确定是前序,中序还是后序
数据结构:
package com.example.chyer.demo;
import java.util.Stack;
public class Test {
private String v;
private Test left;
private Test right;
public static void main(String[] args) {
// 初始化二叉树
Test parent = new Test();
parent.v = "4";
parent.left = new Test();
parent.left.v = "2";
parent.left.left = new Test();
parent.left.left.v = "1";
parent.left.right = new Test();
parent.left.right.v = "3";
parent.right = new Test();
parent.right.v = "6";
parent.right.left = new Test();
parent.right.left.v = "5";
System.out.println("先序遍历:");
parent.preOrder();
System.out.println("中序遍历:");
parent.infixOrder();
System.out.println("后序遍历:");
parent.postOrder();
System.out.println("先序非递归:");
parent.先序非递归(parent);
System.out.println("中序非递归:");
parent.中序非递归(parent);
System.out.println("后序非递归:");
parent.后序非递归(parent);
}
public String toString() {
return this.v;
}
//编写前序遍历的方法
public void preOrder() {
System.out.println(this); //先输出父结点
//递归向左子树前序遍历
if (this.left != null) {
this.left.preOrder();
}
//递归向右子树前序遍历
if (this.right != null) {
this.right.preOrder();
}
}
//中序遍历
public void infixOrder() {
//递归向左子树中序遍历
if (this.left != null) {
this.left.infixOrder();
}
//输出父结点
System.out.println(this);
//递归向右子树中序遍历
if (this.right != null) {
this.right.infixOrder();
}
}
//后序遍历
public void postOrder() {
if (this.left != null) {
this.left.postOrder();
}
if (this.right != null) {
this.right.postOrder();
}
System.out.println(this);
}
public static void 先序非递归(Test root) {
Stack<Test> stack = new Stack<>();
Test node = root;
//节点不为空或者栈不为空都要循环
while (node != null || !stack.empty()) {
// 1. 输出根节点的值
// 2. 保存根节点(方便后面找右节点)
// 3. 找到最左节点
while (node != null) {
System.out.println(node.v);
stack.push(node);
node = node.left;
}
//找到右节点
if (!stack.empty()) {
node = stack.pop();
node = node.right;
}
}
}
public static void 中序非递归(Test root) {
Stack<Test> stack = new Stack<>();
Test node = root;
//节点不为空或者栈不为空都要循环
while (node != null || !stack.empty()) {
// 1. 保存根节点(方便后面找右节点)
// 2. 找到最左节点
while (node != null) {
stack.push(node);
node = node.left;
}
if (!stack.empty()) {
node = stack.pop();
System.out.println(node.v);
node = node.right;
}
}
}
public static void 后序非递归(Test root) {
Stack<Test> stack = new Stack<>();
Test node = root;
Test lastVisit = root;
while (node != null || !stack.empty()) {
while (node != null) {
stack.push(node);
node = node.left;
}
//查看当前栈顶元素
node = stack.peek();
//如果其右子树也为空,或者右子树已经访问
//则可以直接输出当前节点的值
if (node.right == null || node.right == lastVisit) {
System.out.println(node.v);
stack.pop();
// 记录当前输出结果,以备右子树判断
lastVisit = node;
node = null;
} else {
//否则,继续遍历右子树
node = node.right;
}
}
}
}
运行结果: