第十三题:非递归方法实现二叉树的前序,中序,后序,层序遍历(Java)

题目:

请使用非递归的方法,实现二叉树的前序,中序,后序,层序遍历

代码实现:

附带了递归的实现,即使用递归来测试非递归的实现是否正确。

package com.isea.brush.tree;

import java.util.LinkedList;
import java.util.Stack;

public class BinaryTree {
    private Node head;
    private int size;

    private static class Node {
        private int data;
        private Node left;
        private Node right;

        public Node(int data) {
            this.data = data;
        }
    }

    public BinaryTree() {
        head = null;
        size = 0;
    }

    /**
     * 二叉树的先序遍历,非递归实现
     * 实现的思路:使用辅助的数据结构栈来实现,每一次循环出栈,先存放当前节点右边元素,再存放左边元素
     *
     * @param head
     */
    public static void preOrder(Node head) {
        System.out.print("pre-Order:");
        if (head != null) {
            Stack<Node> stack = new Stack<Node>();
            stack.push(head);
            while (!stack.isEmpty()) {
                head = stack.pop(); // 这句代码进行head的移动
                System.out.print(head.data + " ");
                if (head.right != null) {
                    stack.push(head.right);
                }
                if (head.left != null) {
                    stack.push(head.left);
                }
            }
        }
        System.out.println();
    }

    /**
     * 二叉树的中序遍历,非递归实现
     * 实现思路:使用辅助数组栈,从头节点开始,一路向左入栈,直到当前节点为空;然后当前节点指向栈顶弹出的元素
     * 打印当前节点,然后当前节点在指向当前节点的右节点。一直进行此过程。直到栈为空
     *
     * @param head
     */
    public static void inOrder(Node head) {
        System.out.print("in-Order:");

        if (head != null) {
            Stack<Node> stack = new Stack<Node>();
            while (!stack.isEmpty() || head != null) { // head != null 是为了第一次栈为空的时候,往栈中push元素
                if (head != null) {
                    stack.push(head);
                    head = head.left;
                } else {
                    head = stack.pop();
                    System.out.print(head.data + " ");
                    head = head.right;
                }
            }
        }
        System.out.println();
    }

    /**
     * 二叉树的后序遍历的非递归实现
     * 实现思路:上面我们实现了二叉树的先序遍历(中左右)也即当前节点,先将右孩子入栈,在将左孩子入栈,
     * 现在将其修改为中右左(也即当前节点,先将左孩子入栈,在将右孩子入栈),如此我们就实现中右左的结构
     * 但是在打印的时候,我们不打印,我们在将其存放到另外一个栈中去,然后在出栈,就会是(左右中)后续遍历
     *
     * @param head
     */
    public static void postOrder(Node head) {
        System.out.print("post-Order;");
        if (head != null) {
            Stack<Node> stack1 = new Stack<Node>();
            Stack<Node> stack2 = new Stack<Node>();
            stack1.push(head);
            while (!stack1.empty()) {
                head = stack1.pop();
                stack2.push(head);
                if (head.left != null) {
                    stack1.push(head.left);
                }
                if (head.right != null) {
                    stack1.push(head.right);
                }
            }
            while (!stack2.isEmpty()) {
                System.out.print(stack2.pop().data + " ");
            }
        }
        System.out.println();
    }

    /**
     * 二叉树的层序遍历
     * 使用辅助的数据结构:队列来实现。
     *
     * @param head
     */
    public static void levelOrder(Node head) {
        System.out.print("level-Order:");
        if (head == null) {
            return;
        }
        LinkedList<Node> queue = new LinkedList<Node>();
        queue.add(head);
        while (!queue.isEmpty()) {
            head = queue.remove();
            System.out.print(head.data + " ");
            if (head.left != null) {
                queue.add(head.left);
            }
            if (head.right != null) {
                queue.add(head.right);
            }
        }
        System.out.println();
    }

    /**
     * 二叉树的先序遍历
     *
     * @param head 二叉树的根节点
     */
    public static void preOrderRec(Node head) {
        if (head == null) {
            return;
        }
        System.out.print(head.data + " ");
        preOrderRec(head.left);
        preOrderRec(head.right);
    }

    /**
     * 二叉树的中序遍历
     *
     * @param head 二叉树的根节点
     */
    public static void inOrderRec(Node head) {
        if (head == null) {
            return;
        }
        inOrderRec(head.left);
        System.out.print(head.data + " ");
        inOrderRec(head.right);
    }

    /**
     * 二叉树的后序遍历
     *
     * @param head 二叉树的根节点
     */
    public static void postOrderRec(Node head) {
        if (head == null) {
            return;
        }
        postOrderRec(head.left);
        postOrderRec(head.right);
        System.out.print(head.data + " ");
    }


    public static void main(String[] args) {
        Node head = new Node(5);
        head.left = new Node(3);
        head.right = new Node(8);
        head.left.left = new Node(2);
        head.left.right = new Node(4);
        head.left.left.left = new Node(1);
        head.right.left = new Node(7);
        head.right.left.left = new Node(6);
        head.right.right = new Node(10);
        head.right.right.left = new Node(9);
        head.right.right.right = new Node(11);

        // recursive
        System.out.println("==============recursive==============");
        System.out.print("pre-order: ");
        preOrderRec(head);
        System.out.println();
        System.out.print("in-order: ");
        inOrderRec(head);
        System.out.println();
        System.out.print("pos-order: ");
        postOrderRec(head);
        System.out.println();

        // unrecursive
        System.out.println("============unrecursive=============");
        preOrder(head);
        inOrder(head);
        postOrder(head);

        levelOrder(head);
    }
    /**
     * ==============recursive==============
     * pre-order: 5 3 2 1 4 8 7 6 10 9 11 
     * in-order: 1 2 3 4 5 6 7 8 9 10 11 
     * pos-order: 1 2 4 3 6 7 9 11 10 8 5 
     * ============unrecursive=============
     * pre-Order:5 3 2 1 4 8 7 6 10 9 11 
     * in-Order:1 2 3 4 5 6 7 8 9 10 11 
     * post-Order;1 2 4 3 6 7 9 11 10 8 5 
     * level-Order:5 3 8 2 4 7 10 1 6 9 11 
     */

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值