剑指offer-面试题32.2:之字形打印二叉树

题目描述

请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。

思路分析

我们可以注意到当前行为奇数行下一行是从右到左进行访问的,当前行为偶数行是从左到右访问的,呈现的效果是加入的顺序和访问的顺序是相反的,所以我们首先想到利用栈来进行存储。根据前面的从上到下分行打印,我们知道如何进行换行和计算下一行的的节点个数,再添加一个变量curLine表示当前是那行,根据该变量确认如何添加下一行的元素;

二叉树

总结出规律:按之字形打印二叉树我们需要两个栈,在打印某一层结点时,把下一层的子结点保存到相应栈中。如果是奇数层,则先保存左结点再保存右结点,这样换下一行访问时就是先右后左。如果是偶数层,则先保存右结点再保存左结点,访问就是从左到右。例如上图第一行用奇数栈保存C E,当换到下一行时,弹出顺序即访问顺序是E C,第二行用偶数栈保存G H D A然后换行,当再次换行时,弹出访问顺序是A F H G,呈现之字形打印效果;

代码实现
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Stack;

/*
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}
*/
public class Solution {
    public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
        ArrayList<ArrayList<Integer>> res = new ArrayList<>();
        if (pRoot == null) {
            return res;
        }
        int toBeLine = 1, nextLine = 0, curLine = 1;
        TreeNode treeNode;
        ArrayList<Integer> row = new ArrayList<>();

        Stack<TreeNode> oddStack = new Stack<>();
        Stack<TreeNode> evenStack = new Stack<>();
        ///第一个元素
        evenStack.push(pRoot);
        while (!oddStack.isEmpty() || !evenStack.isEmpty()) {
            treeNode = curLine % 2 == 0 ? oddStack.pop() : evenStack.pop();
            row.add(treeNode.val);
            if (curLine % 2 == 1) {
                ///奇数行从左到右入栈
                if (treeNode.left != null) {
                    oddStack.push(treeNode.left);
                    nextLine++;
                }
                if (treeNode.right != null) {
                    oddStack.push(treeNode.right);
                    nextLine++;
                }
            } else {
                ///偶数行从右到左入栈
                if (treeNode.right != null) {
                    evenStack.add(treeNode.right);
                    nextLine++;
                }
                if (treeNode.left != null) {
                    evenStack.add(treeNode.left);
                    nextLine++;
                }
            }
            --toBeLine;
            ///换行
            if (toBeLine == 0) {
                curLine++;
                toBeLine = nextLine;
                nextLine = 0;
                res.add(row);
                row = new ArrayList<>();
            }
        }
        return res;
    }

}
欢迎关注南阁公众号

南阁子也

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值