在上一篇博客中,實現了Java中二叉樹的四種遍歷方式的遞歸實現,接下來,在此實現Java中非遞歸實現二叉樹的前序、中序、后序、層序遍歷,在非遞歸實現中,借助了棧來幫助實現遍歷。前序和中序比較類似,也簡單一些,但是后序遍歷需要兩個棧來進行輔助,稍微復雜一些,層序遍歷中借助了一個隊列來進行實現。
同樣是那棵二叉樹
-
前序遍歷:4 2 1 3 6 5 7 8 10
-
中序遍歷:1 2 3 4 5 6 7 8 10
-
后序遍歷:1 3 2 5 10 8 7 6 4
-
層序遍歷:4 2 6 1 3 5 7 8 10
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
public class Tree<AnyType extends Comparable<? super AnyType>>
{
private static class BinaryNode<AnyType>
{
BinaryNode(AnyType theElement)
{
this(theElement, null, null);
}
BinaryNode(AnyType theElement, BinaryNode<AnyType> lt, BinaryNode<AnyType> rt)
{
element = theElement;
left = lt;
right = rt;
}
AnyType element;
BinaryNode<AnyType> left;
BinaryNode<AnyType> right;
}
private BinaryNode<AnyType> root;
public void insert(AnyType x)
{
root = insert(x, root);
}
public boolean isEmpty()
{
return root == null;
}
private BinaryNode<AnyType> insert(AnyType x, BinaryNode<AnyType> t)
{
if(t == null)
{
return new BinaryNode<>(x, null, null);
}
int compareResult = x.compareTo(t.element);
if(compareResult < 0)
{
t.left = insert(x, t.left);
}
else if(compareResult > 0)
{
t.right = insert(x, t.right);
}
else
{
;
}
return t;
}
/**
* 前序遍歷
* 遞歸
*/
public void preOrder(BinaryNode<AnyType> Node)
{
if (Node != null)
{
System.out.print(Node.element + " ");
preOrder(Node.left);
preOrder(Node.right);
}
}
/**
* 中序遍歷
* 遞歸
*/
public void midOrder(BinaryNode<AnyType> Node)
{
if (Node != null)
{
midOrder(Node.left);
System.out.print(Node.element + " ");
midOrder(Node.right);
}
}
/**
* 后序遍歷
* 遞歸
*/
public void posOrder(BinaryNode<AnyType> Node)
{
if (Node != null)
{
posOrder(Node.left);
posOrder(Node.right);
System.out.print(Node.element + " ");
}
}
/*
* 層序遍歷
* 遞歸
*/
public void levelOrder(BinaryNode<AnyType> Node) {
if (Node == null) {
return;
}
int depth = depth(Node);
for (int i = 1; i <= depth; i++) {
levelOrder(Node, i);
}
}
private void levelOrder(BinaryNode<AnyType> Node, int level) {
if (Node == null || level < 1) {
return;
}
if (level == 1) {
System.out.print(Node.element + " ");
return;
}
// 左子樹
levelOrder(Node.left, level - 1);
// 右子樹
levelOrder(Node.right, level - 1);
}
public int depth(BinaryNode<AnyType> Node) {
if (Node == null) {
return 0;
}
int l = depth(Node.left);
int r = depth(Node.right);
if (l > r) {
return l + 1;
} else {
return r + 1;
}
}
/**
* 前序遍歷
* 非遞歸
*/
public void preOrder1(BinaryNode<AnyType> Node)
{
Stack<BinaryNode> stack = new Stack<>();
while(Node != null || !stack.empty())
{
while(Node != null)
{
System.out.print(Node.element + " ");
stack.push(Node);
Node = Node.left;
}
if(!stack.empty())
{
Node = stack.pop();
Node = Node.right;
}
}
}
/**
* 中序遍歷
* 非遞歸
*/
public void midOrder1(BinaryNode<AnyType> Node)
{
Stack<BinaryNode> stack = new Stack<>();
while(Node != null || !stack.empty())
{
while (Node != null)
{
stack.push(Node);
Node = Node.left;
}
if(!stack.empty())
{
Node = stack.pop();
System.out.print(Node.element + " ");
Node = Node.right;
}
}
}
/**
* 后序遍歷
* 非遞歸
*/
public void posOrder1(BinaryNode<AnyType> Node)
{
Stack<BinaryNode> stack1 = new Stack<>();
Stack<Integer> stack2 = new Stack<>();
int i = 1;
while(Node != null || !stack1.empty())
{
while (Node != null)
{
stack1.push(Node);
stack2.push(0);
Node = Node.left;
}
while(!stack1.empty() && stack2.peek() == i)
{
stack2.pop();
System.out.print(stack1.pop().element + " ");
}
if(!stack1.empty())
{
stack2.pop();
stack2.push(1);
Node = stack1.peek();
Node = Node.right;
}
}
}
/*
* 層序遍歷
* 非遞歸
*/
public void levelOrder1(BinaryNode<AnyType> Node) {
if (Node == null) {
return;
}
BinaryNode<AnyType> binaryNode;
Queue<BinaryNode> queue = new LinkedList<>();
queue.add(Node);
while (queue.size() != 0) {
binaryNode = queue.poll();
System.out.print(binaryNode.element + " ");
if (binaryNode.left != null) {
queue.offer(binaryNode.left);
}
if (binaryNode.right != null) {
queue.offer(binaryNode.right);
}
}
}
public static void main( String[] args )
{
int[] input = {4, 2, 6, 1, 3, 5, 7, 8, 10};
Tree<Integer> tree = new Tree<>();
for(int i = 0; i < input.length; i++)
{
tree.insert(input[i]);
}
System.out.print("遞歸前序遍歷 :");
tree.preOrder(tree.root);
System.out.print("\n非遞歸前序遍歷:");
tree.preOrder1(tree.root);
System.out.print("\n遞歸中序遍歷 :");
tree.midOrder(tree.root);
System.out.print("\n非遞歸中序遍歷 :");
tree.midOrder1(tree.root);
System.out.print("\n遞歸后序遍歷 :");
tree.posOrder(tree.root);
System.out.print("\n非遞歸后序遍歷 :");
tree.posOrder1(tree.root);
System.out.print("\n遞歸層序遍歷:");
tree.levelOrder(tree.root);
System.out.print("\n非遞歸層序遍歷 :");
tree.levelOrder1(tree.root);
}
}
在以上代碼中,preOrder1、midOrder1、posOrder1、levelOrder1四個函數,分別代表了非遞歸實現的二叉樹前序、中序、后序、層序遍歷遍歷。