二叉树的层序遍历

二叉树的层序遍历

前言

本文章中,所有二叉树的定义如下:

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
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

代码小学生王木木

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值