题目:
请使用非递归的方法,实现二叉树的前序,中序,后序,层序遍历
代码实现:
附带了递归的实现,即使用递归来测试非递归的实现是否正确。
package com.isea.brush.tree;
import java.util.LinkedList;
import java.util.Stack;
public class BinaryTree {
private Node head;
private int size;
private static class Node {
private int data;
private Node left;
private Node right;
public Node(int data) {
this.data = data;
}
}
public BinaryTree() {
head = null;
size = 0;
}
/**
* 二叉树的先序遍历,非递归实现
* 实现的思路:使用辅助的数据结构栈来实现,每一次循环出栈,先存放当前节点右边元素,再存放左边元素
*
* @param head
*/
public static void preOrder(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(); // 这句代码进行head的移动
System.out.print(head.data + " ");
if (head.right != null) {
stack.push(head.right);
}
if (head.left != null) {
stack.push(head.left);
}
}
}
System.out.println();
}
/**
* 二叉树的中序遍历,非递归实现
* 实现思路:使用辅助数组栈,从头节点开始,一路向左入栈,直到当前节点为空;然后当前节点指向栈顶弹出的元素
* 打印当前节点,然后当前节点在指向当前节点的右节点。一直进行此过程。直到栈为空
*
* @param head
*/
public static void inOrder(Node head) {
System.out.print("in-Order:");
if (head != null) {
Stack<Node> stack = new Stack<Node>();
while (!stack.isEmpty() || head != null) { // head != null 是为了第一次栈为空的时候,往栈中push元素
if (head != null) {
stack.push(head);
head = head.left;
} else {
head = stack.pop();
System.out.print(head.data + " ");
head = head.right;
}
}
}
System.out.println();
}
/**
* 二叉树的后序遍历的非递归实现
* 实现思路:上面我们实现了二叉树的先序遍历(中左右)也即当前节点,先将右孩子入栈,在将左孩子入栈,
* 现在将其修改为中右左(也即当前节点,先将左孩子入栈,在将右孩子入栈),如此我们就实现中右左的结构
* 但是在打印的时候,我们不打印,我们在将其存放到另外一个栈中去,然后在出栈,就会是(左右中)后续遍历
*
* @param head
*/
public static void postOrder(Node head) {
System.out.print("post-Order;");
if (head != null) {
Stack<Node> stack1 = new Stack<Node>();
Stack<Node> stack2 = new Stack<Node>();
stack1.push(head);
while (!stack1.empty()) {
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().data + " ");
}
}
System.out.println();
}
/**
* 二叉树的层序遍历
* 使用辅助的数据结构:队列来实现。
*
* @param head
*/
public static void levelOrder(Node head) {
System.out.print("level-Order:");
if (head == null) {
return;
}
LinkedList<Node> queue = new LinkedList<Node>();
queue.add(head);
while (!queue.isEmpty()) {
head = queue.remove();
System.out.print(head.data + " ");
if (head.left != null) {
queue.add(head.left);
}
if (head.right != null) {
queue.add(head.right);
}
}
System.out.println();
}
/**
* 二叉树的先序遍历
*
* @param head 二叉树的根节点
*/
public static void preOrderRec(Node head) {
if (head == null) {
return;
}
System.out.print(head.data + " ");
preOrderRec(head.left);
preOrderRec(head.right);
}
/**
* 二叉树的中序遍历
*
* @param head 二叉树的根节点
*/
public static void inOrderRec(Node head) {
if (head == null) {
return;
}
inOrderRec(head.left);
System.out.print(head.data + " ");
inOrderRec(head.right);
}
/**
* 二叉树的后序遍历
*
* @param head 二叉树的根节点
*/
public static void postOrderRec(Node head) {
if (head == null) {
return;
}
postOrderRec(head.left);
postOrderRec(head.right);
System.out.print(head.data + " ");
}
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);
// recursive
System.out.println("==============recursive==============");
System.out.print("pre-order: ");
preOrderRec(head);
System.out.println();
System.out.print("in-order: ");
inOrderRec(head);
System.out.println();
System.out.print("pos-order: ");
postOrderRec(head);
System.out.println();
// unrecursive
System.out.println("============unrecursive=============");
preOrder(head);
inOrder(head);
postOrder(head);
levelOrder(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
* post-Order;1 2 4 3 6 7 9 11 10 8 5
* level-Order:5 3 8 2 4 7 10 1 6 9 11
*/
}