分别采用迭代和栈的方式对二叉树进行遍历。
import java.util.LinkedList;
public class MyTree {
enum Order{
PREORDER, INORDER, POSTORDER;
}
private class Node{
Integer self;
Node left;
Node right;
int hashCode;
public Node(Integer i) {
self = i;
hashCode = i.intValue();
}
public Node(String s) {
self = new Integer(s);
hashCode = self.intValue();
}
public Node(int i) {
self = new Integer(i);
hashCode = self.intValue();
}
@Override
public int hashCode() {
return hashCode;
}
}
private Node root;
private int size=0;
public static void main(String[] args) {
MyTree tree = new MyTree();
tree.add(10);
tree.add(5);
tree.add(15);
tree.add(7);
tree.add(6);
tree.add(1);
tree.add(11);
tree.add(20);
tree.add(14);
tree.add(16);
tree.traversal();
}
public void add(int i){
doAddtoTree(new Node(i));
}
public void add(String s){
doAddtoTree(new Node(s));
}
public void add(Integer i){
doAddtoTree(new Node(i));
size++;
}
public int size() {
return size;
}
public void traversal(){
doTraversalPreOrder();
doTraversalMidOrder();
doTraversalPostOrder();
}
private void doAddtoTree(Node node){
boolean bFound = false;
Node curNode = root;
if(addToRoot(node)) return;
while(!bFound){
if(curNode.hashCode() > node.hashCode()){
if (curNode.left != null){
curNode = curNode.left;
}else{
curNode.left = node;
bFound = true;
}
}else if(curNode.hashCode() < node.hashCode()){
if (curNode.right != null){
curNode = curNode.right;
}else {
curNode.right = node;
bFound = true;
}
}else {
curNode.self = node.self;
bFound = true;
}
}
}
private boolean addToRoot(Node node){
if (root == null){
root = node;
return true;
}else
return false;
}
private void doTraversalPreOrder(){
doRecursion(root, Order.PREORDER);
System.out.println();
doPreInStack(root, true);
System.out.println();
}
private void doTraversalMidOrder(){
doRecursion(root, Order.INORDER);
System.out.println();
doPreInStack(root, false);
System.out.println();
}
private void doTraversalPostOrder(){
doRecursion(root, Order.POSTORDER);
System.out.println();
doPostStack(root);
System.out.println();
}
/*
迭代遍历。前序(PreOrder):先自己(print),再找左子树(有则迭代),无则再找右子树(有则迭代,无则返回)
中序(InOrder):先找左子树(有则迭代),无则自己(print),再找右子树(有则迭代,无则返回)
后序(PostOrder):先找左子树(有则迭代),无则再找右子树(有则迭代),无则自己(print)
*/
private void doRecursion(Node tree, Order ord){
if (ord == Order.PREORDER) print(tree.self);
if (tree.left != null){
doRecursion(tree.left, ord);
}
if (ord == Order.INORDER) print(tree.self);
if (tree.right != null){
doRecursion(tree.right, ord);
}
if (ord == Order.POSTORDER) print(tree.self);
}
private void doPreInStack(Node tree, boolean bPre){
LinkedList<Node> stack = new LinkedList<>();
while((tree != null) || (!stack.isEmpty())){
while(tree != null){
stack.push(tree);
if (bPre) print(tree.self);
tree = tree.left;
}
while((tree==null) && (!stack.isEmpty())){
tree = stack.pop();
if (!bPre)print(tree.self);
tree = tree.right;
}
}
}
/*
* 使用栈后序遍历:
* 1、根压栈
* 2、如果有左孩子,左孩子入栈,如果有右孩子,右孩子入栈,循环直到叶子(左右孩子都没有)
* 3、叶子出栈(并访问自己),访问栈顶(这个叶子的父结点)的右孩子。
* 3.1、如果有右孩子,重复2~3.
* 3.2、如果没有右孩子,继续出栈。
* 4、后序遍历到根节点时栈为空,应结束
*/
private void doPostStack(Node tree) {
Node root = tree;
LinkedList<Node> stack = new LinkedList<>();
while((tree!=null) || (!stack.isEmpty())) {
while(tree!=null) {
stack.push(tree);
if(tree.left!=null) {
tree = tree.left;
}else {
tree = tree.right;
}
}
while((!stack.isEmpty()) && tree == stack.peek().right) {
tree = stack.pop();
print(tree.self);
}
if(!stack.isEmpty()) {
tree = stack.peek().right;
}else {
tree = null;
}
}
}
private void print(Integer i){
System.out.print(i+" ");
}
}
前序:10 5 1 7 6 15 11 14 20 16
中序:1 5 6 7 10 11 14 15 16 20
后序:1 6 7 5 14 11 16 20 15 10