首页 > 其他分享 >【剑指Offer】59、按之字形顺序打印二叉树

【剑指Offer】59、按之字形顺序打印二叉树

时间:2023-08-16 23:55:54浏览次数:43  
标签:之字形 59 temp ArrayList 打印 二叉树 TreeNode null stack

【剑指Offer】59、按之字形顺序打印二叉树

题目描述:

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

解题思路:

这道题仍然是二叉树的遍历,相当于层次遍历,可以和第22题:从上往下打印二叉树 和第60题:把二叉树打印成多行 这几个题对比起来进行分析。

相对而言,本题按之字形顺序打印二叉树是比较复杂的,短时间内不太好分析得到结论,可以通过具体的实例来进行分析,从具体的例子得出普遍的结论。

实际上,层次遍历我们都是借助一定的数据容器来实现的,比如按行打印使用的是队列。在本题,我们使用的是栈,具体分析如下:我们可以设置两个辅助栈,在打印某一层的结点时,将下一层的子结点保存到相应的栈里;如果当前打印的是奇数层(第一层、第三层等),则先保存左子节点再保存右子结点到第一个栈中,如果当前打印的是偶数层(第二层、第四层等),则先保存右子结点再保存左子结点到第二个栈中。

举例:

编程实现(Java):

import java.util.ArrayList;
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;
        Stack[] stack=new Stack[2]; //stack[0]保存偶数层,stack[1]保存奇数层,注意java不支持泛型数组
        stack[0]=new Stack();
        stack[1]=new Stack();
        TreeNode root=pRoot;
        stack[1].push(root);
        int num=1; //当前打印的是第几层
        while((!stack[0].isEmpty())||(!stack[1].isEmpty())){ //有一个栈不为空
            int flag=num%2; //当前要打印的栈
            //int save=flag==0?1:0; //下一层保存在这个栈中
            ArrayList<Integer> row=new ArrayList<>();
            while(!stack[flag].isEmpty()){
                TreeNode temp=(TreeNode)stack[flag].pop();
                if(flag==1) { //当前是奇数行
                    if(temp.left!=null)
                        stack[0].push(temp.left);
                    if(temp.right!=null)
                        stack[0].push(temp.right);
                }else{ //当前是偶数行
                    if(temp.right!=null)
                        stack[1].push(temp.right);
                    if(temp.left!=null)
                        stack[1].push(temp.left);
                }
                row.add(temp.val);
            }
            res.add(row);
            num++;
        } 
        return res;
     }

}

或者可以下面这种写法更好理解一下:

public class Solution {
   public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
        //之字形顺序打印二叉树
        ArrayList<ArrayList<Integer>> res=new ArrayList<>();
        if(pRoot==null)
            return res;
        Stack<TreeNode> stack1=new Stack<>();
        Stack<TreeNode> stack2=new Stack<>();
        stack1.push(pRoot);
        while(!stack1.isEmpty() || !stack2.isEmpty()){
            ArrayList<Integer> list=new ArrayList<>();
            if(!stack1.isEmpty()){
                while(!stack1.isEmpty()){
                    TreeNode temp=stack1.pop();
                    list.add(temp.val);
                    if(temp.left!=null)  //先左后右
                        stack2.push(temp.left);
                    if(temp.right!=null)
                        stack2.push(temp.right);
                }
            }else{
                while(!stack2.isEmpty()){
                    TreeNode temp=stack2.pop();
                    list.add(temp.val);
                    if(temp.right!=null)   //先右后左
                        stack1.push(temp.right);
                    if(temp.left!=null)
                        stack1.push(temp.left);
                }
            }
            res.add(list);
        }
        return res;
    }
}

标签:之字形,59,temp,ArrayList,打印,二叉树,TreeNode,null,stack
From: https://www.cnblogs.com/bujidao1128/p/17636516.html

相关文章

  • 剑指 Offer 37. 序列化二叉树(困难)
    题目:classCodec{public:voidrserialize(TreeNode*root,string&str){//编码递归函数:将树按照前序遍历,放入str字符串中。每个节点元素用','分隔if(root==nullptr){//如果遇到空节点,写入"none"。str+="none,";}el......
  • [代码随想录]Day19-二叉树part08
    题目:235.二叉搜索树的最近公共祖先思路:BST和普通二叉树不同的一点是可以根据特性来找最近公共祖先,只要找到第一个值比p大比q小(假设p<q)的节点返回即可。代码:/***Definitionforabinarytreenode.*typeTreeNodestruct{*Valint*Left*TreeNode......
  • CF1598F RBS
    题目大意定义括号序列为只包括\(\texttt{(}\)和\(\texttt{)}\)的字符串。一个匹配的括号序列(简记为RBS)满足,可以在其中加入\(1\)和\(+\),将其转化为合法的代数式,例如:\(\texttt{()()}\)和\(\texttt{(())}\)是匹配的;\(\texttt{)(}\)和\(\texttt{(}\)和\(\texttt{)}......
  • ARC159
    ARC159前面做过一遍,效果不佳,再来一遍A最优化问题,考虑什么情况最优/不优,猜测\(x\)至多一步到\(y\)所在的方阵中。证明考虑如果\(x\)到其他点,可以到\(y\)所在方阵中对应的点,一定不劣B每次减去\(\gcd\),关注\(\gcd\)变化的条件。容易发现\(\gcd\)至多变化$\log$......
  • CH582 CH592 CH573 Central提高连接速度
    主机连接很慢,怎么解决?主机端开启高速扫描//TRUEtousehighscandutycyclewhencreatinglink#defineDEFAULT_LINK_HIGH_DUTY_CYCLEFALSE//FALSE改成TRUE,启动高速扫描,增加连接速度GAPRole_CentralEstablishLink(DEFAULT_LINK_HIGH_DUTY_CYCLE,......
  • VTK 实例59:加入边界限制的三角剖分(表面重建)
    1#include<vtkAutoInit.h>2VTK_MODULE_INIT(vtkRenderingOpenGL2);3VTK_MODULE_INIT(vtkRenderingFreeType);4VTK_MODULE_INIT(vtkInteractionStyle);56#include<vtkSmartPointer.h>7#include<vtkProperty.h>8#include&......
  • 【剑指Offer】38、二叉树的深度
    题目描述:输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。解题思路:本题相对比较简单。根据二叉树深度的定义,我们有以下理解:如果一棵树只有一个结点,那么它的深度为1。如果根结点只有左子树而没有右子树,那么......
  • [代码随想录]Day18-二叉树part07
    题目:530.二叉搜索树的最小绝对差思路:一个关键问题——BST的中序遍历是由小到大的顺序,也就是说记录遍历的前一个节点,每次比较当前节点-前一个节点的值即可(因为由小到大所以当前>前一个)代码:/***Definitionforabinarytreenode.*typeTreeNodestruct{*Val......
  • cf 598 A
    A.TrickySumtimelimitpertestmemorylimitpertestinputoutput1 to n,butyoushouldtakeallpowersoftwowithminusinthesum.n = 4 thesumisequ......
  • 二叉树:自下而上,从左到右的层次遍历
    利用栈先进后出的特性,将出队元素依次进栈,然后依次出栈即可完成。#include<stdio.h>#include<stdlib.h>#defineMaxSize100//二叉树的结点类型typedefstructNode{intdata;structNode*lchild,*rchild;}TreeNode,*Tree;//队列的结点类型typedefstru......