按之字形顺序打印二叉树

博客介绍了实现之字形打印二叉树的方法。使用双栈 s1 和 s2 分别存储奇数层和偶数层节点,每打印一个节点就将下一层节点按规则入栈。利用栈后进先出特性实现之字形打印,还提到可用 layer 记录层数,stack.empty() 和 arr.isEmpty() 区别不大。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

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

分析:

  • 使用双栈s1 和s2 ,来分别存储奇数层和偶数层的节点,
  • 每打印一个节点,就把此节点的下一层的左右节点加入队列
  • 使用list来记录打印节点的顺序

用到栈的特性:后进先出

  • 打印奇数层 的节点node,并把node的左右子节点遍历入栈,下一层(偶数层)pop出栈就变成了逆序遍历(从右到左);
if (node != null) {
    temp1.add(node.val);
    //System.out.print(node.val + " ");//打印奇数层 的节点node
    s2.push(node.left);//奇数层,正序遍历入栈,下一层(偶数层)pop出栈就变成了逆序遍历
    s2.push(node.right);
}
  •  打印偶数层 的节点node,并把node的右左子节点遍历入栈,下一层(奇数层)pop出栈就变成了顺序遍历(从左到右);
if (node != null) {
    temp2.add(node.val);
   // System.out.print(node.val + " ");//分别打印这一行的元素
    s1.push(node.right);//偶数层,逆序遍历入栈,下一层(奇数层)pop出栈就变成了顺序遍历
    s1.push(node.left);
}

/**

 * 大家的实现很多都是将每层的数据存进ArrayList中,偶数层时进行reverse操作,

 * 在海量数据时,这样效率太低了。

*/

代码:

import java.util.ArrayList;
import java.util.Stack;
public class Test1 {
    public ArrayList<ArrayList<Integer>> Print(TreeNode pRoot) {//最终要返回一个list,且list的每一个元素是 数组ArrayList<Integer>
        int layer = 1;
        //s1存奇数层节点
        Stack<TreeNode> s1 = new Stack<TreeNode>();
        s1.push(pRoot);
        //s2存偶数层节点
        Stack<TreeNode> s2 = new Stack<TreeNode>();

        //list存储打印顺序的数组, list的每一个元素是 数组ArrayList<Integer>
        ArrayList<ArrayList<Integer>> list = new ArrayList<ArrayList<Integer>>();
        while (!s1.empty() || !s2.empty()) {
                ArrayList<Integer> temp1 = new ArrayList<Integer>();
                while (!s1.empty()) {
                    TreeNode node = s1.pop();
                    if (node != null) {
                        temp1.add(node.val);
                        System.out.print(node.val + " ");
                        s2.push(node.left);//奇数层,正序遍历入栈,下一层(偶数层)pop出栈就变成了逆序遍历
                        s2.push(node.right);
                    }
                }
                if (!temp1.isEmpty()) {
                    list.add(temp1);//把temp数组加进来
                    layer++;//换行
                    System.out.println();
                }
                ArrayList<Integer> temp2 = new ArrayList<Integer>();
                while (!s2.empty()) {
                    TreeNode node = s2.pop();
                    if (node != null) {
                        temp2.add(node.val);
                        System.out.print(node.val + " ");//分别打印这一行的元素
                        s1.push(node.right);//偶数层,逆序遍历入栈,下一层(奇数层)pop出栈就变成了顺序遍历
                        s1.push(node.left);
                    }
                }
                if (!temp2.isEmpty()) {
                    //  list.add(temp);//把temp数组加进来
                    layer++;
                    System.out.println();
                }
        }
        return list;//没有输出的返回语句
    }

    public static void main(String[] args) {
        TreeNode root=new TreeNode(8);

        root.left = new TreeNode(6);
        root.right = new TreeNode(10);

        root.left.left = new TreeNode(5);
        root.left.right = new TreeNode(7);

        root.right.left = new TreeNode(9);
        root.right.right = new TreeNode(11);
        Test1 test1 =new Test1();
        test1.Print(root);
    }
}

 打印结果:                                                      

扩展部分:

  • 使用layer来记录层数(因为使用了双栈,非必需)
  • public ArrayList<ArrayList<Integer>> Print(TreeNode pRoot) {//最终要返回一个list,且list的每一个元素是 数组ArrayList<Integer>
            int layer = 1;
            //s1存奇数层节点
            Stack<TreeNode> s1 = new Stack<TreeNode>();
            s1.push(pRoot);
            //s2存偶数层节点
            Stack<TreeNode> s2 = new Stack<TreeNode>();
    
            //list存储打印顺序的数组, list的每一个元素是 数组ArrayList<Integer>
            ArrayList<ArrayList<Integer>> list = new ArrayList<ArrayList<Integer>>();
            while (!s1.empty() || !s2.empty()) {
                if (layer % 2 != 0) {
                    ArrayList<Integer> temp = new ArrayList<Integer>();
                    while (!s1.empty()) {
                        TreeNode node = s1.pop();
                        if (node != null) {
                            temp.add(node.val);
                            System.out.print(node.val + " ");
                            s2.push(node.left);//奇数层,正序遍历入栈,下一层(偶数层)pop出栈就变成了逆序遍历
                            s2.push(node.right);
                        }
                    }
                    if (!temp.isEmpty()) {
                        list.add(temp);//把temp数组加进来
                        layer++;//换行
                        System.out.println();
                    }
                } else {
                    ArrayList<Integer> temp = new ArrayList<Integer>();
                    while (!s2.empty()) {
                        TreeNode node = s2.pop();
                        if (node != null) {
                            temp.add(node.val);
                            System.out.print(node.val + " ");//分别打印这一行的元素
                            s1.push(node.right);//偶数层,逆序遍历入栈,下一层(奇数层)pop出栈就变成了顺序遍历
                            s1.push(node.left);
                        }
                    }
                    if (!temp.isEmpty()) {
                        //  list.add(temp);//把temp数组加进来
                        layer++;
                        System.out.println();
                    }
                }
            }
            return list;//没有输出的返回语句
        }
    

    需要注意:stack.empty() 和arr.  isEmpty()   没什么区别

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值