给定一个二叉树,返回其按层次遍历的节点值。 (即逐层地,从左到右访问所有节点)。
例如:
给定二叉树: [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;
}
};