Java实现二叉树的前、序、后打印(非递归、栈)

代码示例(注释含写代码时思路):

package com.zihao;

import java.util.Stack;

public class traverseDonRecurrence {

    /*3、发现二叉树没定义它的属性*/
    public Node node;

    /*2、结点定义好了,构造或说初始化一棵二叉树呗*/
    public traverseDonRecurrence(Node head){
        this.node = head;
    }

    /*1、成树之前得先有节点,所以先定义结点*/
    static class Node{
        int value;
        Node left;
        Node right;

        /*别忘了构造方法*/
        public Node(int value){
            this.value = value;
        }
    }

    public static void main(String[] args) {
        /*4、把二叉树弄出来
         * start */
        traverseRecurrence.Node head = new traverseRecurrence.Node(1); //new一个头节点
        traverseRecurrence traverseRecurrence = new traverseRecurrence(head);//传入头节点,二叉树有头(根)了
        //不断添加左孩子、右孩子,构成各种各样的二叉树
        traverseRecurrence.node.left = new traverseRecurrence.Node(2);
        traverseRecurrence.node.right = new traverseRecurrence.Node(3);
        traverseRecurrence.node.left.left = new traverseRecurrence.Node(4);
        traverseRecurrence.node.left.right = new traverseRecurrence.Node(5);
        traverseRecurrence.node.right.left = new traverseRecurrence.Node(7);
        traverseRecurrence.node.right.right = new traverseRecurrence.Node(8);
        //.....
        /* end */

        System.out.println("========================开始打印========================");
        System.out.println("========================非递归前序打印开始========================");
        traverseRecurrence.pre(head);
        System.out.println("========================非递归中序打印开始========================");
        traverseRecurrence.in(head);
        System.out.println("========================非递归后序打印开始========================");
        traverseRecurrence.pos(head);
    }

    /** 利用昨晚学习的"非递归(压栈弹栈)"思想,前、中、后序打印二叉树*/

    /*前序
    * 1、压栈(压入头结点)
    * ========= 循环 start
    * 2、弹栈
    * 3、打印
    * 4、先右后左(如果有)
    * ========= end
    * */
    public void pre(Node head){
        if (head == null){
            return;
        }
        Stack<Node> stack = new Stack<>();
        stack.push(head);
        while (!stack.isEmpty()){
            Node cur = stack.pop();
            System.out.println(cur.value);
            if (cur.left != null){
                stack.push(cur.left);
            }
            if (cur.right != null){
                stack.push(cur.right);
            }
        }
    }


    /*中序:
    * 1、从head开始,左边界的所有结点依次入栈
    * 2、从栈中弹出cur打印
    * 3、cur的右子树重复1、2步(如果有)
    * */
    public void in(Node head){
        if (head == null){
            return;
        }
        Stack<Node> stack = new Stack<>();
        while (!stack.isEmpty() || head != null){
            if (head != null){
                stack.push(head);
                head = head.left;
            }else {
                Node cur = stack.pop();
                System.out.println(cur);
                if (cur.right != null){
                    stack.push(cur);
                    head = cur.left;
                }
            }
        }
    }

    /*后序:
    * 思路:首先明确后序的顺序是:左->右->头,前序是:头->左->右,所以前序压栈的顺序是[头-右-左],那现在变一下原前序压栈顺序,
    * 改成[头-左-右],弹栈的时候[头-右-左]不打印,把它压倒另一个栈(下面称为:收集栈),最后打印这个栈[左-右-头]。
    * 1、在原前序打印的代码上作修改,打印 -> 压栈
    * 2、先左后右(如果有)
    * 3、打印收集栈
    * */
    public void pos(Node head){
        if (head == null){
            return;
        }
        Stack<Node> stack = new Stack<>();
        stack.push(head);
        Stack<Node> collectStack = new Stack<>();
        while(!stack.isEmpty()){
            Node cur = stack.pop();
            collectStack.push(cur);
            if (cur.left != null){
                stack.push(cur);
            }
            if (cur.right != null){
                stack.push(cur);
            }
        }
        while (!collectStack.isEmpty()){
            System.out.println(collectStack.pop());
        }
    }

}

你可能感兴趣的:(数据结构与算法,二叉树)