二叉树的一个节点如下:
public static class Node {
public int value;
public Node left;
public Node right;
public Node(int data) {
this.value = data;
}
}
遍历
二叉树最基本的就是递归和非递归的遍历。并分别实现1)先序 2)中序 3)后序三种遍历方式。
递归遍历
5
3 8
2 4 7 10
1 6 9 11
如上二叉树,在进行递归先序遍历时,每个节点实际访问顺序如下(每个都访问三次):
5 3 2 1 1 1 2 3 4 4 4 3 5 8 7 6 6 6 7 7 8 10 9 9 9 10 11 11 11 10 8 5
先序遍历:访问左右节点之前打印head(第一次打印)
5 3 2 1 1 1 2 3 4 4 4 3 5 8 7 6 6 6 7 7 8 10 9 9 9 10 11 11 11 10 8 5
中序遍历:访问左右节点之间打印head(第二次打印)
5 3 2 1 1 1 2 3 4 4 4 3 5 8 7 6 6 6 7 7 8 10 9 9 9 10 11 11 11 10 8 5
后序遍历:访问左右节点之后打印head(第三次打印)
5 3 2 1 1 1 2 3 4 4 4 3 5 8 7 6 6 6 7 7 8 10 9 9 9 10 11 11 11 10 8 5
代码如下:
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 + " ");
}
非递归遍历
先序遍历:另需一个栈stack
1)每次从栈中弹出一个节点Node 2)打印Node 3)压入弹出节点的子节点(先右后左)
中序遍历:另需一个栈stack
1)整棵树的左边界入栈 2)弹出一个节点Node 3)如果有右节点,重复左边界全入栈的操作。没有则继续弹出。
后序遍历:另需两个栈stack1 stack2
1)每次从stack1中弹出一个节点Node压入stack2 3)stack1压入弹出节点的子节点(先左后右)4)对stack2pop
代码如下:
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 posOrderUnRecur(Node head){
System.out.print("pos-order: ");
if(head != null){
Stack<Node> stack1 = new Stack<Node>();
Stack<Node> stack2 = new Stack<Node>();
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 levelOrderTraveral(TreeNode root) {
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
while (!queue.isEmpty()) {
TreeNode node = queue.poll();
System.out.print(node.data + " ");
if (node.left != null) {
queue.add(node.left);
}
if (node.right != null) {
queue.add(node.right);
}
}
}