广度优先搜索保证了在访问任意节点之前,会先访问到它的所有相邻节点,即先访问距离起始节点更近的节点,然后再访问距离起始节点更远的节点。这样可以逐层地遍历图或树的结构,形成一种类似于"广度扩散"的效果。
方法:广度优先搜索
在每一层遍历时,记录该层的节点个数,并将节点值存入一维数组中。然后将该层的子节点按顺序放入队列,继续下一层的遍历,直到遍历完整个二叉树。最终得到的二维数组 ans 就是二叉树的层序遍历结果。
时间复杂度是 O(n),其中 n 是二叉树中的节点数。这是因为每个节点最多进入队列一次,出队列一次,所以时间复杂度是线性的。
空间复杂度为 O(n),其中 n 是二叉树中的节点个数,即队列中最多会存储 n 个节点的指针。
- 创建一个空队列 que 和一个二维数组 ans。
- 将根节点放入队列 que 中。
- 创建一个循环,当队列不为空时,执行以下操作: a. 获取当前队列的长度 size,用于记录当前层的二叉树节点个数。 b. 创建一个一维数组 ans2,用来存放当前层的节点值。 c. 进行 size 次循环,将队列中的节点依次取出:
- 将队列的第一个节点 front 弹出,并将其值存入 ans2。
- 若 front 的左子节点不为空,将左子节点放入队列 que 中。
- 若 front 的右子节点不为空,将右子节点放入队列 que 中。 d. 将 ans2 存入二维数组 ans 中。
- 返回二维数组 ans,即为二叉树的层序遍历结果。
type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
func main() {
nums:=[]int{2,3,4,1,5,8,7,6}
root:=createTree(0,nums)
ansMatrix:=levelOrder(root)
fmt.Println(ansMatrix)
}
//用数组按层序建立二叉树
func createTree(index int,nums []int) *TreeNode {
if index >= len(nums) {
return nil
}
root := &TreeNode{
Val: nums[index],
}
root.Left = createTree(index*2+1, nums)
root.Right = createTree(index*2+2, nums)
return root
}
//102.二叉树层序遍历
func levelOrder(root *TreeNode) [][]int {
//创建一个空队列,指针数组
que:=make([]*TreeNode,0)
//把根节点放入队列
que=append(que,root)
//创建一个二维数组
ans:=make([][]int,0)
// 第一次将根节点放入队列时,应该先判断根节点是否为 nil。
if root == nil{
return ans
}
for len(que)!=0{
//用队列长度记录而每层二叉树元素的个数
//用来作为遍历每层节点放多少次元素进一维数组ans2的次数条件
size:=len(que)
//在二叉树当前层创建一个一位数组用来存放当前层的元素
ans2:=make([]int,0)
for i:=0;i<size;i++{
//因为队首只是一个指针,所以用一个变量存下队首指针
front:=que[0]
ans2=append(ans2,front.Val)//不能用root.val。
//因为每层遍历都需要一个队首的指针来存入数组,存入数组后的队首会被弹出队列
que=que[1:]
if front.Left!=nil{
que=append(que,front.Left)//同理,不能写成root.left。我们要放的是队首的指针,不是根节点的指针。
}
if front.Right!=nil{
que=append(que,front.Right)
}
}
ans=append(ans,ans2)
}
return ans
}