今天学习了二叉树的遍历,以此方式加深印象。
上图
- 定义Node
public static class Node {
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 preOrderUnRecur(Node head) {
System.out.print("pre-order: ");
if (head != null) {
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);
}
}
}
System.out.println();
}
- 中序遍历
定义:按左根右的顺序进行遍历
- 递归方式实现
public static void inOrderRecur(Node head) {
if (head == null) {
return;
}
inOrderRecur(head.left);
System.out.print(head.value + " ");
inOrderRecur(head.right);
}
- 非递归方式实现
public static void inOrderUnRecur(Node head) {
System.out.print("in-order : ");
if (head != null) {
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;
}
}
}
System.out.println();
}
- 后序遍历
定义:按左右根的顺序进行遍历
- 递归方式实现
public static void posOrderRecur(Node head) {
if (head == null) {
return;
}
posOrderRecur(head.left);
posOrderRecur(head.right);
System.out.print(head.value + " ");
}
- 非递归方式实现
//前面讲了先序遍历的非递归实现,后序遍历在其基础上稍作改变
public static void posOrderUnRecur(Node head) {
System.out.print("pos-order: ");
if (head != null) {
Stack<Node> stack1 = new Stack<>();
Stack<Node> stack2 = new Stack<>();
stack1.push(head); //压入栈中
while (!stack1.isEmpty()) {
head = stack1.pop(); //将其弹出并压入stack2中
stack2.push(head);
// 压入stack1后还要弹出并压入stack2
// 因此先压入左节点再压入右节点
// 从stack2中弹出时则为左右根
if (head.left != null) {
stack1.push(head.left);
}
if (head.right != null) {
stack1.push(head.right);
}
}
while (!stack2.isEmpty()) { //打印stack2中弹出的节点值
System.out.print(stack2.pop().value + " ");
}
}
System.out.println();
}
- 测试
public static void main(String[] args) {
Node head = new Node(5);
head.left = new Node(3);
head.left.left = new Node(2);
head.left.left.left = new Node(1);
head.left.right = new Node(4);
head.right = new Node(8);
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();
System.out.println("===========unrecursive=========");
preOrderUnRecur(head);
inOrderUnRecur(head);
posOrderUnRecur(head);
}
- 结果
===========recursive==========
pre-order: 5 3 2 1 4 8 7 6 10 9 11
in-order : 1 2 3 4 5 6 7 8 9 10 11
pos-order: 1 2 4 3 6 7 9 11 10 8 5
===========unrecursive=========
pre-order: 5 3 2 1 4 8 7 6 10 9 11
in-order : 1 2 3 4 5 6 7 8 9 10 11
pos-order: 1 2 4 3 6 7 9 11 10 8 5