LeetCode OJ 之 Binary Tree Zigzag Level Order Traversal (二叉树的曲线层次遍历)

题目:

Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to right, then right to left for the next level and alternate between).

给定一棵二叉树,返回曲线层次遍历的结果(当前行从左到右遍历,下一行就从右到左)

For example:
Given binary tree {3,9,20,#,#,15,7},

    3
   / \
  9  20
    /  \
   15   7

return its zigzag level order traversal as:

[
  [3],
  [20,9],
  [15,7]
]

思路:

广度优先遍历,用一个bool 记录是从左到右还是从右到左,每一层结束就翻转一下。

迭代版代码:

/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<vector<int> > zigzagLevelOrder(TreeNode *root)
    {
        vector<vector<int> > result;//保存结果
        vector<int> path;//当前层的元素
        if(root == NULL)
            return result;
        queue<TreeNode *> que;
        que.push(root);
        int curlen = 1;//当前层的元素个数,初始值为1,只有一个root
        int nextlen = 0;//下一层的元素个数
        bool isRightToLeft = false;//第一次不是从右到左,初始化为false
        while(!que.empty() || curlen != 0)
        {
            TreeNode *p = que.front();
            que.pop();
            path.push_back(p->val);
            curlen--;
            if(p->left)
            {
                que.push(p->left);
                nextlen++;
            }
            if(p->right)
            {
                que.push(p->right);
                nextlen++;
            }
            //如果当前层的元素遍历完,则判断是否是从右到左的顺序,如果是需要先翻转path,再push进result中
            if(curlen == 0)
            {
                if(isRightToLeft)
                    reverse(path.begin(),path.end());
                result.push_back(path);
                path.clear();
                curlen = nextlen;
                nextlen = 0;
                isRightToLeft = !isRightToLeft;//下次设置成反方向
            }
        }
        return result;
    }
};

递归版代码:

/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<vector<int> > zigzagLevelOrder(TreeNode *root)
    {
        vector<vector<int> > result;
        traverse(root,result,1,true);
        return result;
    }
    void traverse(TreeNode *root , vector<vector<int> > &result , int level , bool isLeftToRight)
    {
        if(root == NULL)
            return ;
        if(level > result.size())
            result.push_back(vector<int>());
        if(isLeftToRight)
            result[level-1].push_back(root->val);//在后插入
        else
            result[level-1].insert(result[level-1].begin(),root->val);//在前面插入
        traverse(root->left,result,level+1,!isLeftToRight);//下一层,isLeftToRight要取反
        traverse(root->right,result,level+1,!isLeftToRight);
    }
};



对于二叉树层次遍历,可以使用队列来实现。首先,将二叉树的根结点入队,然后循环执行以下操作:出队并访问出队结点,如果有左孩子结点,将左孩子结点入队;如果有右孩子结点,将右孩子结点入队。直到队列为空为止。 例如,给定二叉树 [3,9,20,null,null,15,7,按层次遍历的结果为: 3 9 20 15 7 其中,根结点3位于第一层,左孩子结点9和右孩子结点20位于第二层,左孩子结点15和右孩子结点7位于第三层。 这种自顶向下的层次遍历可以通过队列结构来实现,每次出队一个结点,访问该结点,并将其子结点入队,直到队列为空。这样可以保证从叶子节点所在层到根节点所在的层,逐层从左向右遍历。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [leetcode107. 二叉树层次遍历 II](https://download.csdn.net/download/weixin_38551059/13759244)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [二叉树层次遍历](https://blog.csdn.net/qq_44722109/article/details/126292665)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值