• 二叉树的前序中序后序遍历


    二叉树的前序遍历

    根节点——左子树——右子树的方式遍历二叉树。

    方法1:递归

    func preorderTraversal(root *TreeNode) (vals []int) {
        var preorder func(*TreeNode)
        preorder = func(node *TreeNode) {
            if node == nil {
                return
            }
            vals = append(vals, node.Val)
            preorder(node.Left)
            preorder(node.Right)
        }
        preorder(root)
        return
    }

    方法2:迭代

    func preorderTraversal(root *TreeNode) (vals []int) {
        stack := []*TreeNode{}
        node := root
        for node != nil || len(stack) > 0 {
            for node != nil {
                vals = append(vals, node.Val)
                stack = append(stack, node)
                node = node.Left
            }
            node = stack[len(stack)-1].Right
            stack = stack[:len(stack)-1]
        }
        return
    }

    复杂度分析

    时间复杂度:O(n)O(n),其中 nn 是二叉树的节点数。每一个节点恰好被遍历一次。

    空间复杂度:O(n)O(n),为迭代过程中显式栈的开销,平均情况下为 O(log n)O(logn),最坏情况下树呈现链状,为 O(n)O(n)。

    二叉树的中序遍历

    按照访问左子树——根节点——右子树的方式遍历这棵树

    方法1:递归版本

    func inorderTraversal(root *TreeNode) (res []int) {
        var inorder func(node *TreeNode)
        inorder = func(node *TreeNode) {
            if node == nil {
                return
            }
            inorder(node.Left)
            res = append(res, node.Val)
            inorder(node.Right)
        }
        inorder(root)
        return
    }

    方法2:迭代版本

    func inorderTraversal(root *TreeNode) (res []int) {
        stack := []*TreeNode{}
        for root != nil || len(stack) > 0 {
            for root != nil {
                stack = append(stack, root)
                root = root.Left
            }
            root = stack[len(stack)-1]
            stack = stack[:len(stack)-1]
            res = append(res, root.Val)
            root = root.Right
        }
        return
    }

    复杂度分析

    时间复杂度:O(n)O(n),其中 nn 为二叉树节点的个数。二叉树的遍历中每个节点会被访问一次且只会被访问一次。

    空间复杂度:O(n)O(n)。空间复杂度取决于栈深度,而栈深度在二叉树为一条链的情况下会达到 O(n)的级别。

    二叉树的后序遍历

    按照访问左子树——右子树——根节点的方式遍历这棵树。

    方法1:递归版本

    func postorderTraversal(root *TreeNode) (res []int) {
        var postorder func(*TreeNode)
        postorder = func(node *TreeNode) {
            if node == nil {
                return
            }
            postorder(node.Left)
            postorder(node.Right)
            res = append(res, node.Val)
        }
        postorder(root)
        return
    }

    方法2:迭代版本

    func postorderTraversal(root *TreeNode) (res []int) {
        stk := []*TreeNode{}
        var prev *TreeNode
        for root != nil || len(stk) > 0 {
            for root != nil {
                stk = append(stk, root)
                root = root.Left
            }
            root = stk[len(stk)-1]
            stk = stk[:len(stk)-1]
            if root.Right == nil || root.Right == prev {
                res = append(res, root.Val)
                prev = root
                root = nil
            } else {
                stk = append(stk, root)
                root = root.Right
            }
        }
        return
    }

    复杂度分析

    时间复杂度:O(n)O(n),其中 nn 是二叉搜索树的节点数。每一个节点恰好被遍历一次。

    空间复杂度:O(n)O(n),为迭代过程中显式栈的开销,平均情况下为 O(log n)O(logn),最坏情况下树呈现链状,为 O(n)O(n)。

  • 相关阅读:
    css表格单元格间距设置
    JavaScript(js)设置输入焦点(focus)
    让div居中的方法
    Window.open()的使用
    getElementsByTagName的用法
    offsetTop获取top值
    js中indexof的使用
    jquery解析json数据
    iframe的使用
    WCF学习笔记Ⅲ
  • 原文地址:https://www.cnblogs.com/dingxiaoqiang/p/14615285.html
Copyright © 2020-2023  润新知