二叉树的前序遍历
根节点——左子树——右子树的方式遍历二叉树。
方法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)。