# [Java算法分析与设计]二叉树非递归实现遍历

package com.chen.arithmetic_test.BiTree_test;

/**
* Created by ChenMP on 2017/7/13.
*/
public class BiTreeNode {
private Object data;
private BiTreeNode leftChild;
private BiTreeNode rightChild;

public BiTreeNode() {
}

public BiTreeNode(Object data) {
this.data = data;
}

public BiTreeNode(Object data, BiTreeNode leftChild, BiTreeNode rightChild) {
this.data = data;
this.leftChild = leftChild;
this.rightChild = rightChild;
}

public Object getData() {
return data;
}

public void setData(Object data) {
this.data = data;
}

public BiTreeNode getLeftChild() {
return leftChild;
}

public void setLeftChild(BiTreeNode leftChild) {
this.leftChild = leftChild;
}

public BiTreeNode getRightChild() {
return rightChild;
}

public void setRightChild(BiTreeNode rightChild) {
this.rightChild = rightChild;
}
}


package com.chen.arithmetic_test.BiTree_test;

import java.util.HashSet;
import java.util.Set;
import java.util.Stack;

/**
* Created by ChenMP on 2017/7/13.
*/
public class NonRecursive {

// 前序遍历（利用非递归的方式遍历二叉树）
public static void preOrder(BiTreeNode root) {
Stack stack = new Stack();

if (root == null)
return;

BiTreeNode curr;
stack.push(root);

while (!stack.isEmpty()) {
curr = (BiTreeNode) stack.pop(); //后进先出
System.out.print("_" + curr.getData()); //首先打印根节点
if (curr.getRightChild() != null)
stack.push(curr.getRightChild()); //将右子节点压栈
if (curr.getLeftChild() != null)
stack.push(curr.getLeftChild()); //将左子节点压栈
}
}

// 中序遍历（利用非递归的方式遍历二叉树）
public static void inOrder(BiTreeNode root) {
Stack stack = new Stack();

if (root == null)
return;

BiTreeNode curr = root;

while (curr != null || !stack.isEmpty()) {
while (curr != null) { //将所有左子节点遍历压栈
stack.push(curr);
curr = curr.getLeftChild();
}

if (!stack.isEmpty()) {
curr = (BiTreeNode) stack.pop(); //获取到栈顶元素打印
System.out.print("_" + curr.getData());
if (curr.getRightChild() != null) {
curr = curr.getRightChild(); //如果有右子节点，便赋值，判断该右子节点下的左子节点
} else {curr = null;} //如果没有则继续出栈
}
}
}

//后序遍历（利用非递归的方式遍历二叉树）
public static void postOrder(BiTreeNode root) {
Stack stack = new Stack();

if (root == null)
return;

BiTreeNode curr = root;
Set<BiTreeNode> set = new HashSet(); //判断是否检验子节点

while (curr != null || !stack.isEmpty()) {
while (curr != null) { //将所有左子节点遍历压栈
stack.push(curr);
curr = curr.getLeftChild();
}

if (!stack.isEmpty()) {
curr = (BiTreeNode) stack.peek();
if (curr.getRightChild() != null && set.add(curr)) {
curr = curr.getRightChild(); //如果有左子节点，便赋值，判断该左子节点下的右子节点
} else { //没有任何子节点，出栈，打印
stack.pop();
System.out.print("_" + curr.getData());
curr = null;
}
}
}
}

}


package com.chen.arithmetic_test.BiTree_test;

/**
* Created by ChenMP on 2017/7/13.
*/
public class Test {

/**二叉树形
*                      A
*             B                   C
*       D                   E            F
*           G
*        H     I
*/
public static BiTreeNode makeTree() {
BiTreeNode b,c,d,e,f,g,h,i;
i = new BiTreeNode(new Character('I'), null, null);
h = new BiTreeNode(new Character('H'), null, null);
g = new BiTreeNode(new Character('G'), h, i);
d = new BiTreeNode(new Character('D'), null, g);
b = new BiTreeNode(new Character('B'), d, null);
e = new BiTreeNode(new Character('E'), null, null);
f = new BiTreeNode(new Character('F'), null, null);
c = new BiTreeNode(new Character('C'), e, f);
return new BiTreeNode(new Character('A'), b, c);
}

public static void main(String[] args) {
BiTreeNode root = Test.makeTree();

System.out.println("前序遍历：");
//        Traverse.preOrder(root);
NonRecursive.preOrder(root);
System.out.println("\n中序遍历：");
//        Traverse.inOrder(root);
NonRecursive.inOrder(root);
System.out.println("\n后序遍历：");
//        Traverse.postOrder(root);
NonRecursive.postOrder(root);
System.out.println("\n层序遍历");
//        Traverse.levOrder(root);
}
}