美文网首页Go算法
(19)Go队列思想实现二叉树的非递归前序和层次遍历

(19)Go队列思想实现二叉树的非递归前序和层次遍历

作者: 哥斯拉啊啊啊哦 | 来源:发表于2019-05-14 21:06 被阅读0次
    leetcode-144
    
    // 用非递归法实现前序遍历,借用go自带的list实现栈的效果
    // go自带的list,推进去的值被包装在element结构里面,element.Value为推进去的值
    func preorderTraversal(root *TreeNode) []int {
        if root == nil {
            return nil
        }
    
        resp := []int{}
    
        // list底层用双链表实现,对头部尾部的插入取出删除操作时间复杂度都是O(1)
        l := list.New()
        // 从头部插入数据
        l.PushFront(root)
    
        for l.Len() != 0 {
            // 从头部取出数据,先进后出队列(栈)
            e := l.Front()
            // list底层取出元素后元素不会删除,进行1步删除操作
            l.Remove(e)
    
            // 断言判定类型
            r, ok := e.Value.(*TreeNode)
            if ok {
                resp = append(resp, r.Val)
            }
    
            // 先进后出,右先进
            if r.Right != nil {
                l.PushFront(r.Right)
            }
            if r.Left != nil {
                l.PushFront(r.Left)
            }
        }
        return resp
    }
    

    提交leetcode,通过

    leetcode-102
    
    方法1,借用先进先出队列,再定义多1个结构提element,用layer来存储层数
    具体实现如下,速度性能在leetcode上97%,还可以,不过层数有更好的实现方法,看2
    type TreeNode struct {
        Val   int
        Left  *TreeNode
        Right *TreeNode
    }
    
    type element struct {
        layer int //存储层数
        node  *TreeNode
    }
    
    func levelOrder(root *TreeNode) [][]int {
        if root == nil {
            return nil
        }
    
        e := &element{0, root}
        res := [][]int{}
    
        l := list.New()
        l.PushFront(e)
    
        for l.Len() != 0 {
            e := l.Back() //先进先出队列
            l.Remove(e)
    
            r, ok := e.Value.(*element)
            if ok {
                layer := r.layer
                n := r.node
    
                if layer < len(res) {
                    res[layer] = append(res[layer], n.Val)
                } else {
                    res = append(res, []int{n.Val})
                }
    
                if n.Left != nil {
                    l.PushFront(&element{layer + 1, n.Left})
                }
                if n.Right != nil {
                    l.PushFront(&element{layer + 1, n.Right})
                }
            }
        }
        return res
    }
    
    方法2:leetcode上的最佳解答,作者未知
    好好理解,特别是层数的优化方法,不用定义多1个变量layer
    func levelOrder2(root *TreeNode) [][]int {
        if root == nil {
            return nil
        }
        res := make([][]int, 0)
    
        queue := make([]*TreeNode, 0)
        queue = append(queue, root)
        n := len(queue)
        arr := make([]int, 0)
    
        for len(queue) > 0 {
            node := queue[0]  // 先进先出队列
            queue = queue[1:] 
            arr = append(arr, node.Val)
    
            n-- // 优化层数的精髓1
    
            if node.Left != nil {
                queue = append(queue, node.Left)
            }
            if node.Right != nil {
                queue = append(queue, node.Right)
            }
    
            // 优化层数的精髓2
            if n == 0 {
                res = append(res, arr)
                n = len(queue) // 优化层数的精髓3
                arr = []int{}
            }
        }
        return res
    }
    
    leetcode-107
    
    思路:在解决102题目的基础上,对结果进行一次反转即可
    func levelOrderBottom(root *TreeNode) [][]int {
        if root == nil {
            return nil
        }
    
        res := [][]int{}
        arr := []int{}
        l := list.New()
        l.PushFront(root)
        length := l.Len()
    
        for l.Len() > 0 {
            e := l.Back() // 先进先出队列
            l.Remove(e)
            length--
    
            r, ok := e.Value.(*TreeNode)
            if ok {
                arr = append(arr, r.Val)
    
                if r.Left != nil {
                    l.PushFront(r.Left)
                }
                if r.Right != nil {
                    l.PushFront(r.Right)
                }
    
                if length == 0 {
                    res = append(res, arr)
                    arr = []int{}
                    length = l.Len()
                }
            }
        }
    
        // 结果翻转
        i, j := 0, len(res)-1
        for i < j {
            res[i], res[j] = res[j], res[i]
            i++
            j--
        }
        return res
    }
    

    提交leetcode,通过

    相关文章

      网友评论

        本文标题:(19)Go队列思想实现二叉树的非递归前序和层次遍历

        本文链接:https://www.haomeiwen.com/subject/aimeaqtx.html