二叉树的层序遍历
前言
本文章中,所有二叉树的定义如下:
type TreeNode struct {
Val int // 数据域 为了方便,我们用简单的int类型
Left *TreeNode // 指向左子树的指针
Right *TreeNode // 指向右子树的指针
}
层序遍历原理
层序遍历二叉树,顾名思义,就是从根节点开始,一层一层往下遍历,直到遍历完整棵树。
相关习题
题目 | 难度 | 出现频率 | 推荐指数 |
---|---|---|---|
102.二叉树的层序遍历 | 中等 | 🤩🤩🤩🤩🤩 | 🤩🤩🤩🤩🤩 |
107.二叉树的层次遍历II | 中等 | 🤩🤩🤩 | 🤩🤩🤩 |
199.二叉树的右视图 | 中等 | 🤩🤩🤩🤩🤩 | 🤩🤩🤩🤩🤩 |
637.二叉树的层平均值 | 简单 | 🤩🤩 | 🤩🤩 |
429.N叉树的前序遍历 | 中等 | 🤩🤩 | 🤩🤩🤩 |
515.在每个树行中找最大值 | 中等 | 🤩🤩 | 🤩🤩🤩 |
116.填充每个节点的下一个右侧节点指针 | 中等 | 🤩🤩🤩 | 🤩🤩🤩🤩 |
117.填充每个节点的下一个右侧节点指针II | 中等 | 🤩🤩 | 🤩🤩🤩 |
103.二叉树的锯齿形层序遍历 | 中等 | 🤩🤩 | 🤩🤩🤩 |
重点和难点:
重点就是用队列,难点就是要记录当前层的层号(其实一点不难)
如果需要获取层高,就一定要两轮循环才可以解决问题
模板
一定要把模板背得滚瓜烂熟,这样写代码才轻松舒适
无需获取层高,简单的遍历
func LayerRangeStack(root *TreeNode) []int {
if root == nil {
return nil
}
ans := make([]int, 0)
// 第一步 把头节点入队列
var queue = []*TreeNode{root}
for len(queue) > 0 {
//1.出队
temp := queue[0]
queue = queue[1:]
ans = append(ans, temp.Val)
if temp.Left != nil {
queue = append(queue, temp.Left)
}
if temp.Right != nil {
queue = append(queue, temp.Right)
}
}
return ans
}
需要获取层高的
如果需要获取层高,就一定要两层循环,外层循环树的高度,内层循环遍历当前层的宽度
// LayerRangeStack 使用队列实现二叉树的层序遍历
func LayerRangeStack(root *TreeNode) []int {
if root == nil {
return nil
}
ans := make([]int, 0)
// 第一步 把头节点入队列
var queue = []*TreeNode{root}
for len(queue) > 0 {
size := len(queue) // 获取队列长度
fmt.Println("队列长度",size)
for i := 0; i < size; i++ {
//1.出队
temp := queue[0]
queue = queue[1:]
ans = append(ans, temp.Val)
if temp.Left != nil {
queue = append(queue, temp.Left)
}
if temp.Right != nil {
queue = append(queue, temp.Right)
}
}
fmt.Println("===========================")
}
return ans
}
题解
102. 二叉树的层序遍历
这道题就是一道典型的需要获取层高的遍历
两层循环嘛,很简单,掌握了获取层高遍历的模板很容易写出来,这里直接上代码
go语言版本的:
func LevelOrder(root *TreeNode) [][]int {
if root == nil{
return nil
}
ans := [][]int{} // 接受结果集的二维数组
queue := []*TreeNode{root} // 创建队列,并将头节点入队
// 循环遍历 如果对列不为空
for len(queue) > 0{
size := len(queue) // 获取当前队列的大小
tempArr := []int{}
for i := 0; i < size; i++ {
// 从队列中弹出一个元素
node:= queue[0]
queue = queue[1:]
tempArr = append(tempArr, node.Val)
if node.Left != nil{
queue = append(queue,node.Left)
}
if node.Right != nil{
queue = append(queue,node.Right)
}
}
ans = append(ans,tempArr)
}
return ans
}
107. 二叉树的层序遍历 II
这道题和上面一道类似,不过他对层的遍历顺序为自底向上的层序遍历
换汤不换药,至于怎么翻转,说白了,添加到结果集的时候可以做手脚对吧,以前是append到二维数组,我们现在使用addFirst效果的方法,或者我们用栈也行对吧
go:(我是使用栈实现的)
func LevelOrderBottom(root *TreeNode) [][]int {
if root == nil{
return nil
}
ans := [][]int{}
stack := [][]int{}
queue := []*TreeNode{root}
for len(queue) > 0{
size := len(queue)
tempArr := []int{}
for i := 0; i < size; i++ {
node := queue[0]
queue = queue[1:]
tempArr = append(tempArr, node.Val)
if node.Left != nil{
queue = append(queue, node.Left)
}
if node.Right != nil{
queue = append(queue, node.Right)
}
}
stack = append(stack, tempArr)
}
for len(stack) > 0{
ans = append(ans, stack[len(stack)-1])
stack = stack[:len(stack)-1]
}
return ans
}
429. N 叉树的层序遍历
还是他妈的换汤不换药
// Node N叉树
type Node struct {
Val int
Children []*Node
}
func levelOrder(root *Node) [][]int {
if root == nil{
return nil
}
ans := [][]int{}
queue := []*Node{root}
for len(queue) > 0 {
size := len(queue)
tArr := []int{}
for i := 0; i < size; i++ {
node := queue[0]
queue = queue[1:]
tArr = append(tArr, node.Val)
for j := 0; j < len(node.Children); j++ {
queue = append(queue, node.Children[j])
}
}
ans = append(ans, tArr)
}
return ans
}
515. 在每个树行中找最大值
这道题最恶心的就是 你的max值要怎么初始化?max:=int(math.Inf(-1)) //负无穷
func LargestValues(root *TreeNode) []int {
if root == nil{
return nil
}
ans := []int{}
queue := []*TreeNode{root}
for len(queue) > 0{
size := len(queue)
max:=int(math.Inf(-1)) //负无穷
for i := 0; i < size; i++ {
node := queue[0]
queue = queue[1:]
if node.Val > max{
max = node.Val
}
if node.Left != nil{
queue = append(queue, node.Left)
}
if node.Right != nil{
queue = append(queue, node.Right)
}
}
ans = append(ans, max)
}
return ans
}
103. 二叉树的锯齿形层序遍历
这道题核心还是在获取层高的同时层序遍历二叉树,我们可以判断层高是否是基数,如果是基数,反转当前层的数组即可
// 定义反转数组的函数
func reverseArr(num []int)[]int{
arrLen := len(num)
for i := 0; i < arrLen/2; i++ {
num[arrLen-1-i],num[i] = num[i],num[arrLen-1-i]
}
return num
}
func zigzagLevelOrder(root *TreeNode) [][]int {
if root == nil{
return nil
}
ans := [][]int{}
queue := []*TreeNode{root}
for i:=0;len(queue) > 0;i++ {
size := len(queue)
tempArr := []int{}
for j := 0; j < size; j++ {
var node *TreeNode
node = queue[0]
queue = queue[1:]
tempArr = append(tempArr, node.Val)
if node.Left != nil{
queue = append(queue, node.Left)
}
if node.Right != nil{
queue = append(queue, node.Right)
}
}
if i % 2 != 0{
tempArr = reverseArr(tempArr)
}
ans = append(ans, tempArr)
}
return ans
}