package main
import "fmt"
/*
给定一个二叉树,返回其按层次遍历的节点值。 (即逐层地,从左到右访问所有节点)。
例如:
给定二叉树:[3,9,20,8,null,15,7],
3
/ \
9 20
/\ / \
8 nil 15 7
其层次遍历结果:
[
[3],
[9,20],
[15,7]
]
二叉树动画学习网站:https://www.cs.usfca.edu/~galles/visualization/BST.html
*/
//定义二叉树节点
type TreeNode2020 struct {
Val int
Left, Right *TreeNode2020
}
//创建一个二叉树节点
func createNode(nodeVaL int) (node *TreeNode2020) {
if nodeVaL == -1 { //代表null节点
return nil
}
node = &TreeNode2020{
Val: nodeVaL,
Left: nil,
Right: nil,
}
return
}
//创建二叉树,通过中序遍历的数组
func createTreeByMidSearch(midArr []int) (root *TreeNode2020) {
valArr := midArr //备份一个,队列
//首先,创建根节点
root = createNode(valArr[0])
valArr = valArr[1:] //相当于pop出前一个,向后移动一位
nodeArr := []*TreeNode2020{root} //保存二叉树所有的节点信息,为了下次接着给子节点赋值
for len(valArr) > 0 {
cur := nodeArr[0]
nodeArr = nodeArr[1:] //相当于pop出前一个,向后移动一位,节点与val是一一对应的
cur.Left = createNode(valArr[0]) //左叶子节点
valArr = valArr[1:] //相当于pop出前一个,向后移动一位
if cur.Left != nil {
nodeArr = append(nodeArr,cur.Left )
}
cur.Right = createNode(valArr[0]) //右叶子节点
valArr = valArr[1:] //相当于pop出前一个,向后移动一位
if cur.Right != nil {
nodeArr = append(nodeArr,cur.Right )
}
}
return root
}
//------按照---层级--遍历------递归----------时间复杂度O(n2)-----------------
var thisLevel [][]int
func LevelSearch(root *TreeNode2020,level int){
if root == nil{
return
}
if len(thisLevel) < level+1 {
//thisLevel[level] = make([]int,0) //错误方式,未初始化
thisLevel = append(thisLevel,make([]int,0) ) //必须append
}
thisLevel[level] = append(thisLevel[level], root.Val)
LevelSearch(root.Left,level+1)
LevelSearch(root.Right,level+1)
}
//---------------------递推----------时间复杂度0(N)---------------------
func BFSLevelOrder(root *TreeNode2020)(res [][]int){
if root == nil{
return
}
list := make([]*TreeNode2020,0) //队列,pop,push
list = append(list, root) //push第一个节点
for len(list)>0{
tempList := make([]*TreeNode2020,0) //一行临时存储
tempRes := make([]int,0) //一行临时存储
for len(list) > 0{ //逐层遍历,直到队列清空,说明这一层遍历完毕
first := list[0]
list = list[1:] //pop,层里元素减一
tempRes = append(tempRes, first.Val)
if first.Left != nil{
tempList = append(tempList, first.Left)
}
if first.Right != nil{
tempList = append(tempList, first.Right)
}
}
// 一层遍历完成后,把临时一层结果放到 二维数组中
res = append(res, tempRes)
list = list[:0] //队列清空,,目的是只保存同一层的节点,因为要逐层打印
list = append(list, tempList...)
}
return
}
func main() {
fmt.Println("二叉树的层次遍历两种方式,2020-11-20")
valArr := []int{3,9,20,8,-1,15,7}
root := createTreeByMidSearch(valArr) //先创建二叉树
//LevelSearch(root,0) //递归,,层级遍历打印
//for key, value := range thisLevel { //递归,,层级遍历打印
// fmt.Printf("%d========%+v\n",key,value)
//}
for key, value := range BFSLevelOrder(root) { //递推,,层级遍历打印
fmt.Printf("层数:%d ========%+v\n",key,value)
}
}