非递归遍历二叉树是使用栈压栈和弹栈时机不同的思想,在非递归先序遍历中,根据"根左右"的访问顺序不同,先访问当前数据,然后依次压入右儿子和左子;在非递归后序遍历中,需要达到"左右根"的顺序,所以使用两个栈,栈2只存储访问的节点,根据先序遍历的思想修改顺序"根右左",先访问当前节点,然后依次压入左儿子和右儿子,最后输出栈2;在非递归中序遍历中,若当前节点不为空,就压栈,当前节点指向左儿子,若为空且栈不为空,就弹栈,当前节点指向右儿子.

import java.util.Stack;
public class TreeTraversal {
    public static class Node{
        public int value;
        public Node left;
        public Node right;
        public Node(int Value) {
            value = Value;
        }
    }

    public void preOrder(Node head) {
        if(head != null) {
            System.out.print(head.value + " ");
            if(head.left != null) {
                preOrder(head.left);
            }
            if(head.right != null) {
                preOrder(head.right);
            }
        }
    }

    public void inOrder(Node root) {
        if(root != null) {
            if(root.left != null) {
                inOrder(root.left);
            }
            System.out.print(root.value + " ");
            if(root.right != null) {
                inOrder(root.right);
            }
        }
    }

    public  void postOrder(Node root) {
        if(root != null) {
            if(root.left != null) {
                postOrder(root.left);
            }
            if(root.right != null) {
                postOrder(root.right);
            }
            System.out.print(root.value + " ");
        }
    }

    //根据"根左右"的思想进行压栈弹栈
    public void preOrder2(Node root) {
        System.out.println("非递归先序遍历树:");
        if(root != null) {
            Stack s = new Stack();
            s.push(root);
            while(!s.isEmpty()) {
                root = s.pop();
                System.out.print(root.value + " ");
                if(root.right != null) {
                    s.push(root.right);
                }
                if(root.left != null) {
                    s.push(root.left);
                }
            }
        }
    }

    public void inOrder2(Node root) {
        System.out.println("非递归中序遍历树:");
        if(root != null) {
            Stack s = new Stack();
            while(root != null || !s.isEmpty()) {
                if(root != null) {
                    s.push(root);
                    root = root.left;
                }else {
                    root = s.pop();
                    System.out.print(root.value + " ");
                    root = root.right;
                }
            }
        }
    }
    //根据非递归先序遍历的思想使用两个栈,s1压栈,s2弹栈.
    public void postOrder2(Node root) {
        System.out.println("非递归后序遍历树");
        if(root != null) {
        Stack s1 = new Stack();
        Stack s2 = new Stack();
        s1.push(root);
        while(!s1.isEmpty()) {
            root = s1.pop();
            s2.push(root);
            if(root.left != null) {
                s1.push(root.left);
            }
            if(root.right != null) {
                s1.push(root.right);
            }
        }
        while(!s2.isEmpty()) {
        System.out.print(s2.pop().value+ " ");  
        }
    }
}

    public static void main(String[] args) {
        Node root = new Node(1);
        Node a = new Node(2);
        Node b = new Node(3);
        Node c = new Node(4);
        Node d = new Node(5);
        Node e = new Node(6);
        Node f = new Node(7);
        root.left = a;
        root.right = b;
        a.left = c;
        a.right = d;
        b.left = e;
        b.right = f;
        TreeTraversal tree = new TreeTraversal();
        System.out.println("递归先序遍历树");
        tree.preOrder(root);
        System.out.println();
        System.out.println("递归中序遍历树");
        tree.inOrder(root);
        System.out.println();
        System.out.println("递归后序遍历树");
        tree.postOrder(root);
        System.out.println("\n");
        tree.preOrder2(root);
        System.out.println();
        tree.inOrder2(root);
        System.out.println();
        tree.postOrder2(root);
        System.out.println();
    }
}

运行结果:
二叉树的遍历(递归与非递归)_第1张图片