按之字形顺序打印二叉树

题目依旧来自《剑指Offer》和牛客网在线编程。

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

import java.util.ArrayList;

/*
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) {

    }

}

【分析1】首先我们根据题目的描述,能够找到该题的解决模型为二叉树的层次遍历。只不过普通的层次遍历是针对每一层都只是从左到右遍历。这里题目要求奇数层是从左到右遍历,而偶数层则是从右到左遍历的。

【分析2】我们知道二叉树的层次遍历是通过队列来实现的,队列的特点就是先进先出(FIFO),因此能实现在奇数层从左到右遍历访问。既然队列难以实现从左至右遍历,那么栈这种后进先出(LIFO)的结构能够实现从左到右访问呢?答案是肯定的。我们可以使用两个栈来实现,栈S1存放奇数层数据,栈S2存放偶数层数据。S2中的数据好理解,因为只要以先左子树再右子树的顺序进栈后,再出栈的顺序就变成了先右子树出栈,然后左子树出栈了。

【分析3】此时出现了另外一个问题,当奇数层(第一层除外)进栈后,想要实现从左到右的顺序遍历,那么在遍历上一层偶数层的结点的进栈顺序就要发生改变,不能再以默认的先左子树再右子树的顺序进栈,因为栈的特点是后进先出(LIFO)。因此分析到这里我们发现:针对奇数层对应的栈S1来说,出栈后访问结点;如果结点具有左子树,则将该结点的左子树加入到偶数栈S2中;如果结点具有右子树,则将该结点的右子树加入到偶数栈S2中。针对偶数层对应的栈S2来说,出栈后访问结点;如果结点具有右子树,则将该结点的右子树加入到奇数栈S1中;如果结点具有左子树,则将该结点的左子树加入到奇数栈S1中。

【分析4】分析到这里,我们需要解决最后一个问题,就是如何判断当前所处的层是奇数层还是偶数层。因此我们需要设置一个全局变量来记录层数,默认值为1,代表第一层。根据上面的分析,我们可以看出,由于将奇数层与偶数层分开,因此,当栈S1或栈S2为空时,说明这一层遍历完成,将层数加一。

【代码】

import java.util.*;

/*
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_list = new ArrayList<>();
        int layer = 1;
        //s1存奇数层节点
        Stack<TreeNode> s1 = new Stack<TreeNode>();
        s1.push(pRoot);
        //s2存偶数层节点
        Stack<TreeNode> s2 = new Stack<TreeNode>();
        while(!s1.empty() || !s2.empty()){
            if(layer%2 != 0){
                ArrayList<Integer> list = new ArrayList<>();
                while(!s1.empty()){
                    TreeNode t = s1.pop();
                    if(t != null){
                        list.add(t.val);
                        s2.push(t.left);
                        s2.push(t.right);
                    }
                }
                if (!list.isEmpty()) {
                    res_list.add(list);
                    layer++;
                }
            }else{
                ArrayList<Integer> list = new ArrayList<>();
                while(!s2.empty()){
                    TreeNode t = s2.pop();
                    if(t != null){
                        list.add(t.val);
                        s1.push(t.right);
                        s1.push(t.left);
                    }
                }
                if (!list.isEmpty()) {
                    res_list.add(list);
                    layer++;
                }
            }
        }
        return res_list;
    }

}

猜你喜欢

转载自blog.csdn.net/weixin_36378917/article/details/80507052