对二叉树实现之字形打印

题目描述:
请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,其他行以此类推。
队列实现
使用队列实现二叉树的之字形打印,跟层序打印二叉树其实是一样的思路,只不过需要设置一个标记位,因为奇数行实现的是从左到右的打印顺序,而偶数行是从右到左的打印顺序,所以要根据标志位实现每层的一个反转。

二叉树的结构体代码

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>> vec;
        //定义个队
        queue<TreeNode *> qtTree;
        //定义个标志位,通过分析可以看到,之字形打印的时候,奇数行是先右子树后左子树保存,偶数行相反
        int flag=0;
        //看看pRoot是不是空的
        if(pRoot==nullptr)return vec;
        //不是空的,进队
        qtTree.push(pRoot);
        while(!qtTree.empty()){
            //定义个一维向量
             vector<int> layer;
            //首先看看每层有多少元素
            int stasize = qtTree.size();
            while(stasize--){
                //出队
                TreeNode *node;
                node = qtTree.front();
                //删除队头元素
                qtTree.pop();
                //正常保存
                layer.push_back(node->val);
                //正常进队
                if(node->left)qtTree.push(node->left);
                if(node->right)qtTree.push(node->right);
            }
            //看看是偶数行还是奇数行,每次标记位都需要置为反向的标记,方便下一次执行
            if(flag==0){
            	//奇数行的话正常从左到右保存,直接将一维向量赋值给二维向量即可
                vec.push_back(layer);
                flag=1;
            }
            else {
            	//偶数行的话需要先进行向量的反转,然后再赋值给二维向量。
                reverse(layer.begin(), layer.end());
                vec.push_back(layer);
                flag=0;
            }
        }
        return vec;
    }
    
};

下面是用栈实现的二叉树之字形打印,两个栈交替存储,感觉思路上理解起来比使用队列要顺,毕竟栈是先进后出,在之字形存储的时候比使用队列再进行反转要好理解。

class Solution {
public:
        //使用栈存储每层的节点
    vector<vector<int> > Print(TreeNode* pRoot) {
        //首先,定义一个二维向量
        vector<vector<int>> vec;
        //定义两个栈交替存放上下两层的节点
        stack<TreeNode *> sta1;
        stack<TreeNode *> sta2;
        //判断根节点是否存在
        if(pRoot==nullptr)return vec;
        //进栈
        sta1.push(pRoot);
        while(!sta1.empty()||!sta2.empty()){
            //定义一个一维向量,存储一层的节点数据
            vector<int> layer;
            TreeNode *node;
            //从左往右依次进栈
            while(!sta1.empty()){
                node=sta1.top();
                sta1.pop();
                layer.push_back(node->val);
                if(node->left)sta2.push(node->left);
                if(node->right)sta2.push(node->right);
            }
            //得到一层数据,只要不是空的就放到二维向量里面
            if(!layer.empty())vec.push_back(layer);
            //清空一维的向量,继续下一次存取。两次一个循环
            //这个地方容易出错,第一次没加,而且还找不到原因,就是输出比正常输出多了几个
            layer.clear();
            //从右往左依次进栈
            while(!sta2.empty()){
                node=sta2.top();
                sta2.pop();
                layer.push_back(node->val);
                if(node->right)sta1.push(node->right);
                if(node->left)sta1.push(node->left);
            }
            if(!layer.empty())vec.push_back(layer);
        }
        return vec;
    }
    
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是小峰呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值