Z字型打印二叉树

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

1、用两个栈实现

package test04;
import java.util.ArrayList;
import java.util.Stack;
/* * 注意从第一层开始,每一层的节点都是先进入相应的栈,在出栈,最后按照出栈的顺序,add到每一层的tempList里面 * 再把每一层的tempList add到result中,最终返回 * 例如,从一颗二叉树的根节点开始,因为根节点为第一层,为奇数层。所以先把第一层的根节点push到奇数栈odd里面 * 进入while(当size不等于0时,说明整个二叉树还没有遍历完)循环,判断if条件,此时每次从奇数栈odd中pop,都将该节点 * 的左右子节点按照先左后右的顺序push到偶数栈even中,每循环一次,都要把刚才从奇数栈odd中pop的元素add到这一 * 个的临时tempList中,当stackSize==1时,说明这一层已经遍历完了,此时把每一层的tempList add到reslut中,当while * 条件成立,说明整个二叉树已经遍历完,最终返回result。 * */
public class test05 {
    public ArrayList<ArrayList<Integer>> Print(TreeNode pRoot) {
        ArrayList<ArrayList<Integer>> result = new ArrayList<>();
        if (pRoot == null) {
            return result;
        }
        int stackSize;
        boolean isOdd = true;//控制当前遍历的是奇数层还是偶数层

        Stack<TreeNode> odd = new Stack<>();//保存奇数层节点的栈
        odd.push(pRoot);

        Stack<TreeNode> even = new Stack<>();//保存偶数层节点的栈

        ArrayList<Integer> tempList = new ArrayList<>();

        while (odd.size() != 0 || even.size() != 0) {//说明整个二叉树还没有遍历完
            TreeNode root;
            if (isOdd) {//假如当前是奇数层,则它的下一层是先保存左子节点,再保存右子节点
                stackSize = odd.size();
                root = odd.pop();
                if (root.left != null) {
                    even.push(root.left);
                }
                if (root.right != null) {
                    even.push(root.right);
                }
            } else {
                stackSize = even.size();
                root = even.pop();
                if (root.right != null) {
                    odd.push(root.right);
                }
                if (root.left != null) {
                    odd.push(root.left);
                }
            }
            tempList.add(root.val);
            if (stackSize == 1) {//Stack不能弹空栈,所以要提前判空,注意因为这个stackSize是在pop之前赋值的,所以判空为==1,
                isOdd = !isOdd;//把上一层奇数层遍历完,isOdd设置为false,准备遍历下一层偶数层
                result.add(tempList);
                tempList = new ArrayList<>();//为每一层创建一个ArrayList对象
            }
        }
        return result;
    }
}

2、用LinkList链表实现,因为它是一个双向链表

package test04;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;

public class test06 {
    public ArrayList<ArrayList<Integer>> Print(TreeNode pRoot) {
        ArrayList<ArrayList<Integer>> ret = new ArrayList<>();
        if (pRoot == null) {
            return ret;
        }
        ArrayList<Integer> list = new ArrayList<>();//list是存每一层的节点
        LinkedList<TreeNode> queue = new LinkedList<>();//
        queue.addLast(null);// 层分隔符
        queue.addLast(pRoot);// 把根节点添加到queue中
        boolean leftToRight = true;// 开始的时候从左向右遍历
        while (queue.size() != 1) {
            TreeNode node = queue.removeFirst();//取出LinkedList中的第一个节点,并将该节点从LinkedList中删除
            if (node == null) {// 假如达到层分隔符
                Iterator<TreeNode> iter = null;
                if (leftToRight) {
                    iter = queue.iterator();// 从前向后遍历
                } else {
                    iter = queue.descendingIterator();// 从后向前遍历
                }
                leftToRight = !leftToRight;
                while (iter.hasNext()) {// 遍历每一层的节点,存到list集合中
                    TreeNode temp = (TreeNode)iter.next();//注意这里的细节问题,这里的(TreeNode)可以省略,因为前面声明
                    //iter的时候已经指定了泛型Iterator的类型为TreeNode假如前面不指定,这里一定要加上
                    list.add(temp.val);
                }
                ret.add(new ArrayList<>(list));// 把每一层的list集合存到ret集合中
                //ret.add(list);
                list.clear();// list集合clear,为存下一层做准备
                queue.addLast(null);
                continue;//必须要这一句,因为假如node==null,再判断node.lef或者node.right会出现空指针异常
            }
            if (node.left != null) {
                queue.addLast(node.left);
            }
            if (node.right != null) {
                queue.addLast(node.right);
            }
        }
        return ret;
    }
}

参考

    原文作者:Z字形编排问题
    原文地址: https://blog.csdn.net/FutureFlyme/article/details/72791700
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞