文章目录
- 二叉树层序遍历模板
- 102. 二叉树的层序遍历
- 107. 二叉树的层序遍历 II
- 199. 二叉树的右视图
- 637. 二叉树的层平均值
- 515. 在每个树行中找最大值
- 429. N 叉树的层序遍历
- 116. 填充每个节点的下一个右侧节点指针
- 117. 填充每个节点的下一个右侧节点指针 II
二叉树层序遍历模板
我们之前讲过了关于二叉树的深度优先遍历
的文章:前中后序遍历的递归法和迭代法。
接下来我们再来介绍二叉树的另一种遍历方式:层序遍历
。
层序遍历一个二叉树。就是从左到右一层一层的去遍历二叉树。这种遍历的方式和我们之前讲过的都不太一样。
需要借用一个辅助数据结构即队列来实现,队列先进先出,符合一层一层遍历的逻辑,而用栈先进后出适合模拟深度优先遍历也就是递归的逻辑。
而这种层序遍历方式就是图论中的广度优先遍历
,只不过我们应用在二叉树上。
如图所示:将每层的元素从左至右加入队列,取出时就会先取出左节点,并将当前节点的左右节点又加入队尾,接着从队列取出下一个元素,将它的左右节点同样加入队尾,以此类推。那怎么确认取出多少个元素的时候可认为当前层的元素都取完了呢?这就需要一个变量来记录啦,这个变量其实就是每轮循环开始时队列的长度,当前长度就是当前层的所有元素,该轮循环的后续操作就是将下一层的所有节点加入队尾。
这样就实现了层序从左到右遍历二叉树。
代码如下:这份代码也可以作为二叉树层序遍历的模板,打十个就靠它了。
Go代码如下
102. 二叉树的层序遍历
迭代法
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func levelOrder(root *TreeNode) [][]int {
if root == nil {
return [][]int{}
}
res := make([][]int,0)
queue := make([]*TreeNode,0)
queue = append(queue,root)
for len(queue) != 0 {
// 当前层的元素个数,以及定义存当前层结果的数组
queueSize := len(queue)
curLevelRes := make([]int,0)
// 取出当前层所有元素,并依次加入下一层的元素
for i := 0; i < queueSize ;i++ {
curNode := queue[0]
queue = queue[1:len(queue)]
curLevelRes = append(curLevelRes,curNode.Val)
// 当前节点的左右节点加入队列
if curNode.Left != nil {
queue = append(queue,curNode.Left)
}
if curNode.Right != nil {
queue = append(queue,curNode.Right)
}
}
// 当前层遍历完成,将当前层结果加入最终结果中
res = append(res,curLevelRes)
}
return res
}
递归法
// 层序遍历递归法
func levelOrder(root *TreeNode) [][]int {
if root == nil {
return [][]int{}
}
res := make([][]int,0)
preOrder(root,0,&res) //根节点在第0层
return res
}
/*直接使用二叉树的前序遍历的递归形式即可,只是递归的时候,要多传一个参数,
就是该节点属于第几层的,很简单,子节点所在层数是父节点所在层数加一*/
func preOrder(node *TreeNode,level int,res *[][]int) {
//如果level是新层,则在res中继续添加一个[]int用于存这一次的结点的值
if len(*res) == level {
culLevelRes := make([]int,0)
*res = append(*res,culLevelRes)
}
//将结点的值添加到res中对应的层的[]int中
(*res)[level] = append((*res)[level],node.Val)
//递归遍历左右子节点
if node.Left != nil {
preOrder(node.Left,level + 1,res)
}
if node.Right != nil {
preOrder(node.Right,level + 1,res)
}
}
102. 二叉树的层序遍历
102. 二叉树的层序遍历
给你二叉树的根节点 root
,返回其节点值的 层序遍历
。 (即逐层地,从左到右访问所有节点)。
示例 1:
输入:root = [3,9,20,null,null,15,7]
输出:[[3],[9,20],[15,7]]
示例 2:
输入:root = [1]
输出:[[1]]
示例 3:
输入:root = []
输出:[]
提示:
- 树中节点数目在范围 [0, 2000] 内
- -1000 <= Node.val <= 1000
Go 代码迭代法
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func levelOrder(root *TreeNode) [][]int {
if root == nil {
return [][]int{}
}
res := make([][]int,0)
queue := make([]*TreeNode,0)
queue = append(queue,root)
for len(queue) != 0 {
// 当前层的元素个数,以及定义存当前层结果的数组
queueSize := len(queue)
curLevelRes := make([]int,0)
// 取出当前层所有元素,并依次加入下一层的元素
for i := 0; i < queueSize ;i++ {
curNode := queue[0]
queue = queue[1:len(queue)]
curLevelRes = append(curLevelRes,curNode.Val)
// 当前节点的左右节点加入队列
if curNode.Left != nil {
queue = append(queue,curNode.Left)
}
if curNode.Right != nil {
queue = append(queue,curNode.Right)
}
}
// 当前层遍历完成,将当前层结果加入最终结果中
res = append(res,curLevelRes)
}
return res
}
Go代码递归法
// 层序遍历递归法
func levelOrder(root *TreeNode) [][]int {
if root == nil {
return [][]int{}
}
res := make([][]int,0)
preOrder(root,0,&res) //根节点在第0层
return res
}
/*直接使用二叉树的前序遍历的递归形式即可,只是递归的时候,要多传一个参数,
就是该节点属于第几层的,很简单,子节点所在层数是父节点所在层数加一*/
func preOrder(node *TreeNode,level int,res *[][]int) {
//如果level是新层,则在res中继续添加一个[]int用于存这一次的结点的值
if len(*res) == level {
culLevelRes := make([]int,0)
*res = append(*res,culLevelRes)
}
//将结点的值添加到res中对应的层的[]int中
(*res)[level] = append((*res)[level],node.Val)
//递归遍历左右子节点
if node.Left != nil {
preOrder(node.Left,level + 1,res)
}
if node.Right != nil {
preOrder(node.Right,level + 1,res)
}
}
107. 二叉树的层序遍历 II
107. 二叉树的层序遍历 II
给你二叉树的根节点 root
,返回其节点值 自底向上的层序遍历 。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)
示例 1:
输入:root = [3,9,20,null,null,15,7]
输出:[[15,7],[9,20],[3]]
示例 2:
输入:root = [1]
输出:[[1]]
示例 3:
输入:root = []
输出:[]
提示:
- 树中节点数目在范围 [0, 2000] 内
- -1000 <= Node.val <= 1000
Go代码
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func levelOrderBottom(root *TreeNode) [][]int {
// 和102题一样,就是普通的层序遍历,不过遍历完成后,结果需要倒序一下
if root == nil {
return [][]int{}
}
res := make([][]int,0)
queue := make([]*TreeNode,0)
queue = append(queue,root)
for len(queue) > 0 {
queueSize := len(queue)
curLevelRes := make([]int,0)
for i := 0;i < queueSize;i++{
curNode := queue[0]
queue = queue[1:]
curLevelRes = append(curLevelRes,curNode.Val)
if curNode.Left != nil {
queue = append(queue,curNode.Left)
}
if curNode.Right != nil {
queue = append(queue,curNode.Right)
}
}
res = append(res,curLevelRes)
}
// 反转结果
left := 0
right := len(res)-1
for left < right {
res[left],res[right] = res[right],res[left]
left++
right--
}
return res
}
199. 二叉树的右视图
199. 二叉树的右视图
给定一个二叉树的 根节点 root
,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。
示例 1:
输入: [1,2,3,null,5,null,4]
输出: [1,3,4]
示例 2:
输入: [1,null,3]
输出: [1,3]
示例 3:
输入: []
输出: []
提示:
- 二叉树的节点个数的范围是 [0,100]
- -100 <= Node.val <= 100
Go代码
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func rightSideView(root *TreeNode) []int {
// 层序遍历之后,返回每层最后一个元素即可
if root == nil {
return []int{}
}
res := make([]int,0)
queue := make([]*TreeNode,0)
queue = append(queue,root)
for len(queue) > 0 {
queueSize := len(queue)
curLevelRes := make([]int,0)
for i := 0;i < queueSize;i++{
curNode := queue[0]
queue = queue[1:]
curLevelRes = append(curLevelRes,curNode.Val)
if curNode.Left != nil {
queue = append(queue,curNode.Left)
}
if curNode.Right != nil {
queue = append(queue,curNode.Right)
}
}
// 只保留当前层最右边的元素,即当前层最后一个元素
res = append(res,curLevelRes[len(curLevelRes) - 1])
}
return res
}
637. 二叉树的层平均值
637. 二叉树的层平均值
给定一个非空二叉树的根节点 root
, 以数组的形式返回每一层节点的平均值。与实际答案相差
1
0
−
5
10^{-5}
10−5 以内的答案可以被接受。
示例 1:
输入:root = [3,9,20,null,null,15,7]
输出:[3.00000,14.50000,11.00000]
解释:第 0 层的平均值为 3,第 1 层的平均值为 14.5,第 2 层的平均值为 11 。
因此返回 [3, 14.5, 11] 。
示例 2:
输入:root = [3,9,20,15,7]
输出:[3.00000,14.50000,11.00000]
提示:
- 树中节点数量在 [1, 104] 范围内
- -2^31 <= Node.val <= 2^31 - 1
Go代码
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func averageOfLevels(root *TreeNode) []float64 {
// 层序遍历之后,返回每层的平均值即可
if root == nil {
return []float64{}
}
res := make([]float64,0)
queue := make([]*TreeNode,0)
queue = append(queue,root)
for len(queue) > 0 {
queueSize := len(queue)
curLevelRes := make([]int,0)
for i := 0;i < queueSize;i++{
curNode := queue[0]
queue = queue[1:]
curLevelRes = append(curLevelRes,curNode.Val)
if curNode.Left != nil {
queue = append(queue,curNode.Left)
}
if curNode.Right != nil {
queue = append(queue,curNode.Right)
}
}
// 只保留当前层最右边的元素,即当前层最后一个元素
res = append(res,getAvgOfArr(curLevelRes))
}
return res
}
func getAvgOfArr(arr []int) float64 {
sum := 0
for _,num:= range arr {
sum += num
}
return float64(sum) / float64(len(arr))
}
515. 在每个树行中找最大值
515. 在每个树行中找最大值
给定一棵二叉树的根节点 root
,请找出该二叉树中每一层的最大值。
示例1:
输入: root = [1,3,2,5,3,null,9]
输出: [1,3,9]
示例2:
输入: root = [1,2,3]
输出: [1,3]
提示:
- 二叉树的节点个数的范围是 [ 0 , 1 0 4 ] [0,10^4] [0,104]
- − 2 31 < = N o d e . v a l < = 2 31 − 1 -2^{31} <= Node.val <= 2^{31} - 1 −231<=Node.val<=231−1
Go代码
代码和637题几乎一样
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func largestValues(root *TreeNode) []int {
// 层序遍历之后,返回每层的最大值即可
if root == nil {
return []int{}
}
res := make([]int,0)
queue := make([]*TreeNode,0)
queue = append(queue,root)
for len(queue) > 0 {
queueSize := len(queue)
curLevelRes := make([]int,0)
for i := 0;i < queueSize;i++{
curNode := queue[0]
queue = queue[1:]
curLevelRes = append(curLevelRes,curNode.Val)
if curNode.Left != nil {
queue = append(queue,curNode.Left)
}
if curNode.Right != nil {
queue = append(queue,curNode.Right)
}
}
// 只保留当前层最右边的元素,即当前层最后一个元素
res = append(res,getMaxOfArr(curLevelRes))
}
return res
}
func getMaxOfArr(arr []int) int {
maxVal := arr[0]
for _,num:= range arr {
if num > maxVal {
maxVal = num
}
}
return maxVal
}
429. N 叉树的层序遍历
429. N 叉树的层序遍历
给定一个N
叉树,返回其节点值的层序遍历。(即从左到右,逐层遍历)。
树的序列化输入是用层序遍历,每组子节点都由null
值分隔(参见示例)。
示例 1:
输入:root = [1,null,3,2,4,null,5,6]
输出:[[1],[3,2,4],[5,6]]
示例 2:
输入:root = [1,null,2,3,4,5,null,null,6,7,null,8,null,9,10,null,null,11,null,12,null,13,null,null,14]
输出:[[1],[2,3,4,5],[6,7,8,9,10],[11,12,13],[14]]
提示:
- 树的高度不会超过 1000
- 树的节点总数在 [0, 10^4] 之间
Go 代码
/**
* Definition for a Node.
* type Node struct {
* Val int
* Children []*Node
* }
*/
func levelOrder(root *Node) [][]int {
// 思路和102题二叉树的层序遍历是一模一样的
if root == nil {
return [][]int{}
}
res := make([][]int,0)
queue := make([]*Node,0)
queue = append(queue,root)
for len(queue) > 0 {
curLevelRes := make([]int,0)
queueSize := len(queue)
for i := 0;i < queueSize;i++ {
curNode := queue[0]
queue = queue[1:]
curLevelRes = append(curLevelRes,curNode.Val)
// 下一层,与二叉树层序遍历的唯一区别
for j := 0;j < len(curNode.Children);j++{
queue = append(queue,curNode.Children[j])
}
}
res = append(res,curLevelRes)
}
return res
}
116. 填充每个节点的下一个右侧节点指针
116. 填充每个节点的下一个右侧节点指针
给定一个 完美二叉树 ,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:
struct Node {
int val;
Node *left;
Node *right;
Node *next;
}
填充它的每个 next
指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next
指针设置为 NULL
。
初始状态下,所有 next
指针都被设置为 NULL
。
示例 1:
输入:root = [1,2,3,4,5,6,7]
输出:[1,#,2,3,#,4,5,6,7,#]
解释:给定二叉树如图 A所示,你的函数应该填充它的每个 next 指针,以指向其下一个右侧节点,如图 B 所示。序列化的输出按层序遍历排列,同一层节点由 next指针连接,‘#’ 标志着每一层的结束。
示例 2:
输入:root = []
输出:[]
提示:
- 树中节点的数量在 [0, 2^12 - 1] 范围内
- -1000 <= node.val <= 1000
进阶:
- 你只能使用常量级额外空间。
- 使用递归解题也符合要求,本题中递归程序占用的栈空间不算做额外的空间复杂度。
Go 代码
/**
* Definition for a Node.
* type Node struct {
* Val int
* Left *Node
* Right *Node
* Next *Node
* }
*/
func connect(root *Node) *Node {
if root == nil {
return nil
}
queue := make([]*Node,0)
queue = append(queue,root)
for len(queue) != 0 {
// 当前层的元素个数,以及定义存当前层结果的数组
queueSize := len(queue)
curLevelRes := make([]*Node,0)
// 取出当前层所有元素,并依次加入下一层的元素
for i := 0; i < queueSize ;i++ {
curNode := queue[0]
queue = queue[1:]
curLevelRes = append(curLevelRes,curNode)
// 当前节点的左右节点加入队列
if curNode.Left != nil {
queue = append(queue,curNode.Left)
}
if curNode.Right != nil {
queue = append(queue,curNode.Right)
}
}
// 当前层遍历完成,当前层的节点前一个节点的Next连接同层节点的下一个节点
for i := 0;i < len(curLevelRes) - 1;i++ {
curLevelRes[i].Next = curLevelRes[i+1]
}
}
return root
}
117. 填充每个节点的下一个右侧节点指针 II
117. 填充每个节点的下一个右侧节点指针 II
给定一个二叉树:
struct Node {
int val;
Node *left;
Node *right;
Node *next;
}
填充它的每个 next
指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next
指针设置为 NULL
。
初始状态下,所有 next
指针都被设置为 NULL
。
示例 1:
输入:root = [1,2,3,4,5,null,7]
输出:[1,#,2,3,#,4,5,7,#]
解释:给定二叉树如图 A所示,你的函数应该填充它的每个 next 指针,以指向其下一个右侧节点,如图 B 所示。序列化输出按层序遍历顺序(由 next 指针连接),‘#’ 表示每层的末尾。
示例 2:
输入:root = []
输出:[]
提示:
- 树中的节点数在范围 [0, 6000] 内
- -100 <= Node.val <= 100
进阶:
- 你只能使用常量级额外空间。
- 使用递归解题也符合要求,本题中递归程序的隐式栈空间不计入额外空间复杂度。
Go代码
与116题代码一模一样
/**
* Definition for a Node.
* type Node struct {
* Val int
* Left *Node
* Right *Node
* Next *Node
* }
*/
func connect(root *Node) *Node {
if root == nil {
return nil
}
queue := make([]*Node,0)
queue = append(queue,root)
for len(queue) != 0 {
// 当前层的元素个数,以及定义存当前层结果的数组
queueSize := len(queue)
curLevelRes := make([]*Node,0)
// 取出当前层所有元素,并依次加入下一层的元素
for i := 0; i < queueSize ;i++ {
curNode := queue[0]
queue = queue[1:]
curLevelRes = append(curLevelRes,curNode)
// 当前节点的左右节点加入队列
if curNode.Left != nil {
queue = append(queue,curNode.Left)
}
if curNode.Right != nil {
queue = append(queue,curNode.Right)
}
}
// 当前层遍历完成,当前层的节点前一个节点的Next连接同层节点的下一个节点
for i := 0;i < len(curLevelRes) - 1;i++ {
curLevelRes[i].Next = curLevelRes[i+1]
}
}
return root
}