vlambda博客
学习文章列表

二叉树层次遍历go实现2种方式

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)
    }
}