剑指offer(59):按之字形顺序打印二叉树

题目描述

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

思路:使用一个双端队列,当奇数层的时候从队头出队列访问,从队尾入队列,先左孩子入队列后右孩子入队列;当偶数层的时候,从队尾出队列访问结点,从队头入队列,先右孩子入队列,后左孩子入队列

C++实现:

/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};
*/
class Solution {
public:
    vector<vector<int> > Print(TreeNode* pRoot) {
        vector<vector<int> > result;
        if(pRoot){
            //定义变量
            deque<TreeNode*> dequeRoot;  //设置一个双端队列用来存储结点
            vector<int> order;           //设置一个vector用来存储当前层的顺序信息
            TreeNode* q;                 //临时结点
            int dSize = 0;//存储当前队列的个数,即当前层结点的个数
            int level = 0;//当前是第一层,根据奇数层,偶数层有不同的遍历方法
            
            dequeRoot.push_back(pRoot);  //根节点入队列
            
            while(!dequeRoot.empty()){
                dSize = dequeRoot.size();   //当前队列长度即当前层的结点个数
                level++;                    //层数++
                for(int i=0;i<dSize;i++){
                    if(level%2==1){ //奇数层,结点从队列头出队列,从队列尾入队列,先左孩子后右孩子
                        q = dequeRoot.front();
                        dequeRoot.pop_front();
                        if(q->left)
                            dequeRoot.push_back(q->left);
                        if(q->right)
                            dequeRoot.push_back(q->right);
                    }else{      //偶数层,结点从队尾出队列,从队头入队列,先右孩子后左孩子
                        q = dequeRoot.back();
                        dequeRoot.pop_back();
                        if(q->right)
                            dequeRoot.push_front(q->right);
                        if(q->left)
                            dequeRoot.push_front(q->left);
                    }
                    order.push_back(q->val);  //当前结点值存储到vector中
                }
                //存储该层的遍历顺序,并清空order,为下一层的遍历做准备
                result.push_back(order);
                order.clear();
            }
        }
        return result;
    }
    
};

看评论区的思路:使用两个栈或者使用一个队列和一个栈

 用java实现使用两个栈的思路,要注意的是ArrayList直接add是浅拷贝,因此需要

import java.util.*;
public class Solution {
    public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
        ArrayList<ArrayList<Integer> > result = new ArrayList<ArrayList<Integer> >();
        if(pRoot != null){
            
            Stack<TreeNode> s1 = new Stack<TreeNode>();//存储奇数层结点
            Stack<TreeNode> s2 = new Stack<TreeNode>();//存储偶数层结点
            TreeNode q;
            
            s1.add(pRoot);
            while(!s1.empty() || !s2.empty()){
                ArrayList<Integer> order1 = new ArrayList<Integer>();
                while(!s1.empty()){
                    q = s1.pop();
                    order1.add(q.val);
                    if(q.left != null) s2.add(q.left);
                    if(q.right != null) s2.add(q.right);
                }
                if(order1.size() != 0)
                    result.add(order1);
                
                ArrayList<Integer> order2 = new ArrayList<Integer>();
                while(!s2.empty()){
                    q = s2.pop();
                    order2.add(q.val);
                    if(q.right != null) s1.add(q.right);
                    if(q.left != null) s1.add(q.left);
                }
                if(order2.size() != 0)
                    result.add(order2);
            }
            
        }
        return result;
    }

}

原文地址:https://www.cnblogs.com/ttzz/p/13493098.html