剑指offer编程题—把二叉树打印成多行


题目描述
从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。

解题思路
思路1
使用两个队列辅助实现。类似于上一篇按照之字形打印二叉树的思想,这里使用两个辅助队列p,q,一个用于遍历奇数层结点,一个用于遍历偶数层结点。一个队列为空时即代表当前层次遍历完成。转入另一个队列遍历下一层结点。
1)根节点为空,直接返回;
2)根节点不为空,根节点入队列;
3)当两个队列都不为空,依次遍历两个队列,遍历队列p的时候,依次访问队列p中的结点,获取当前结点的值存入临时容器tmpv中,同时将当前层次结点的孩子结点按照先左后右的顺序存入另一个队列q中。当前队列为空时,即当前层次遍历结束,遍历结果tmpv放入结果集result,清空tmpv,转入队列q继续遍历,即开始遍历树的下一层,直到两个队列都为空;

/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};
*/
class Solution {
public:
        vector > Print(TreeNode* pRoot) {
            vector > result;
            if(!pRoot)
                return result;
            vector tmp;
            TreeNode* curNode;
            queue p,q;
            p.push(pRoot);
            while(!p.empty() || !q.empty()){
                while(!p.empty()){
                    curNode=p.front();
                    p.pop();
                    tmp.push_back(curNode->val);
                    if(curNode->left) q.push(curNode->left);
                    if(curNode->right) q.push(curNode->right);
                }
                if(!tmp.empty()){
                    result.push_back(tmp);
                    tmp.clear();
                }
                while(!q.empty()){
                    curNode=q.front();
                    q.pop();
                    tmp.push_back(curNode->val);
                    if(curNode->left) p.push(curNode->left);
                    if(curNode->right) p.push(curNode->right);
                }
                if(!tmp.empty()){
                    result.push_back(tmp);
                    tmp.clear();
                }
            }
            return result;
        }
     
};

思路2
使用一个队列辅助实现。思想是在每一层的末尾添加一个结束标识flag,使用层次遍历的思想,每次遇到flag即当前层次访问完成,打印一行。那么入队的时候什么时候该添加flag呢?
1)根节点为空,直接返回;
2)根节点不为空,根节点入队,因为树根结点为树的第一层,只有一个结点,所以flag也入队,标志第一层的末尾;
3)队列不为空时,从队头逐个取出当前结点,当前结点不为flag,访问,并将其左右孩子结点依次入队;当前结点为flag,表示该层结点遍历完成,打印该层结点,注意此时该层的下一层结点作为该层结点的孩子结点已经在队列中了,故将flag入队,标志下一层的末尾。
最后还要注意判断是否所有节点遍历完成。

/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};
*/
class Solution {
public:
        vector > Print(TreeNode* pRoot) {
            vector > result;
            if(!pRoot)
                return result;
            vector tmpv;
            TreeNode* flag=NULL;
            TreeNode* curNode;
            queue q;
            q.push(pRoot);
            q.push(flag);
            while(!q.empty()){
                curNode=q.front();
                q.pop();
                if(curNode==flag ){
                    if(tmpv.empty()) break; //当所有元素都遍历完后,跳出循环
                    result.push_back(tmpv);
                    tmpv.clear();
                    q.push(flag);
                }
                else{
                    tmpv.push_back(curNode->val);
                    if(curNode->left) q.push(curNode->left);
                    if(curNode->right) q.push(curNode->right);
                }
            }
            return result;
        }
    
};

你可能感兴趣的:(剑指offer编程题—把二叉树打印成多行)