二叉树的层次遍历(队列的应用)

给定一个二叉树,返回其按层次遍历的节点值。 (即逐层地,从左到右访问所有节点)。

例如:
给定二叉树: [3,9,20,null,null,15,7],

3

/
9 20
/
15 7
返回其层次遍历结果:

[
[3],
[9,20],
[15,7]
]
二叉树层次遍历的题目,第一想到的就是官渡优先搜索。
下面做一个总结:
树的遍历方法一般分为两种:一种是广度优先遍历(BFS),一种是深度优先遍历(DFS),
BFS:对应的就是二叉树的层次遍历;
DFS:可以分为二叉树的前序遍历,中序遍历,后序遍历这三种遍历方法;
解决这些遍历的方法有三种:
1、递归(最直接想到的方法)
2、迭代法,使用数据结构(BFS用到队列,DFS用到栈)
下面使用递归的方法
思路:
最简单的解法就是递归,首先确认树非空,然后调用递归函数 helper(node, level),参数是当前节点和节点的层次。程序过程如下:

输出列表称为 levels,当前最高层数就是列表的长度 len(levels)。比较访问节点所在的层次 level 和当前最高层次 len(levels) 的大小,如果前者更大就向 levels 添加一个空列表。
将当前节点插入到对应层的列表 levels[level] 中。
递归非空的孩子节点:helper(node.left / node.right, level + 1)。
C++

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<vector<int>> helper(TreeNode* Node, int level, vector<vector<int>> res){
        vector<int>re;
        if(res.size()==level){
            cout<<res.size();
            re = {};
            res.push_back(re);
            
        }
        res[level].push_back(Node->val);
        
        if(Node->left){
            res=helper(Node->left,level+1,res);
            // return res;
        }
        if(Node->right){
            res=helper(Node->right,level+1,res);
            // return res;
        }
        return res;
    }
    vector<vector<int>> levelOrder(TreeNode* root) {
        //层次遍历的方法用到的是BFS
        //先用递归实现
        vector<vector<int>> res={};
        if(!root){
            return {};
        }
        return helper(root,0,res);
    }
};

python3

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def levelOrder(self, root: TreeNode) -> List[List[int]]:
        res=[]
        if not root:
            return res
        return self.helper(root, 0, res)
        
    def helper(self,node: TreeNode, level,res) -> List[List[int]]:
        if len(res)==level:
            res.append([])
        res[level].append(node.val)
        if node.left:
            res = self.helper(node.left, level+1, res)
        if node.right:
            res = self.helper(node.right, level+1,res)
        return res
        

复杂度分析

时间复杂度:O(N)O(N),因为每个节点恰好会被运算一次。
空间复杂度:O(N)O(N),保存输出结果的数组包含 N 个节点的值。

第二种方法:迭代法:
在访问过程中,我们只需要将同一层中的节点同时入队列即可。在将该queue中所有元素出队列的同时,将下一层的元素进队列,完成交接。

C++

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        //层次遍历的方法用到的是BFS
        //运用队列方法
        vector<vector<int>> res;
        if(!root){
            return res;
        }
        queue<TreeNode*>Q;
        Q.push(root);
        TreeNode* p;
        while(!Q.empty()){
            vector<int> temp;
		    int width=Q.size();//这里非常重要,不能省略,用Q.size()在下面代替,因为下面有Q.pop()操作导致最后的size()不稳定
            for(int i=0;i<width;i++){
                p = Q.front();//指向进入队列的根节点
                temp.push_back(p->val);
                Q.pop();//导出根节点
                if(p->left){
                    Q.push(p->left);
                }
                if(p->right){
                    Q.push(p->right);
                }
            }
            res.push_back(temp);
        }
        return res;
    }
};


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值