Binary Tree different traversal ways
Preorder
Order: Root -> Left -> Right
// Recursion
func preorderTraversal(root *TreeNode) []int {
// Time complexity: O(n)
// Spatial complexity: O(n)
res := []int{}
var preOrder func(*TreeNode)
preOrder = func(root *TreeNode) {
if root == nil {
return
}
res = append(res, root.Val) // root
preOrder(root.Left) // left
preOrder(root.Right) // right
}
preOrder(root)
return res
}
// Iterate
func preorderTraversal(root *TreeNode) []int {
// Time complexity: O(n)
// Spatial complexity: O(n)
if root == nil {
return nil
}
res := make([]int, 0)
stack := make([]*TreeNode, 0)
for len(stack) > 0 || root != nil {
for root != nil {
res = append(res, root.Val) // root
stack = append(stack, root)
root = root.Left // left
}
// pop
node := stack[len(stack)-1]
stack = stack[:len(stack)-1]
root = node.Right // right
}
return res
}
Inorder
Order: Left -> Root -> Right
// Recursion
func inorderTraversal(root *TreeNode) []int {
// Time complexity: O(n)
// Spatial complexity: O(n)
res := []int{}
var inorder func(*TreeNode)
inorder = func(root *TreeNode) {
if root == nil {
return
}
inorder(root.Left) // left
res = append(res, root.Val) // root
inorder(root.Right) // right
}
inorder(root)
return res
}
// Iterate
func inorderTraversal(root *TreeNode) []int {
// Time complexity: O(n)
// Spatial complexity: O(n)
if root == nil {
return nil
}
res := make([]int, 0)
stack := make([]*TreeNode, 0)
for len(stack) > 0 || root != nil {
for root != nil {
stack = append(stack, root)
root = root.Left // left
}
node := stack[len(stack)-1]
stack = stack[:len(stack)-1]
res = append(res, node.Val) // root
root = node.Right // right
}
return res
}
Postorder
Order: Left -> Right -> Root
// Recursion
func postorderTraversal(root *TreeNode) []int {
// Time complexity: O(n)
// Spatial complexity: O(n)
res := []int{}
var postorder func(*TreeNode)
postorder = func(root *TreeNode) {
if root == nil {
return
}
postorder(root.Left) // left
postorder(root.Right) // right
res = append(res, root.Val) // root
}
postorder(root)
return res
}
// Iterate
func postorderTraversal(root *TreeNode) []int {
// Time complexity: O(n)
// Spatial complexity: O(n)
if root == nil {
return nil
}
res := make([]int, 0)
stack := make([]*TreeNode, 0)
// will check if right node has been pop
var lastVisit *TreeNode
for len(stack) > 0 || root != nil {
for root != nil {
stack = append(stack, root)
root = root.Left // left
}
node := stack[len(stack)-1]
// root will pop after right node
if node.Right == nil || node.Right == lastVisit {
stack = stack[:len(stack)-1]
res = append(res, node.Val) // root
lastVisit = node
} else {
root = node.Right // right
}
}
return res
}
Levelorder
Order: from left to right, level by level
// Recursion (BFS)
func levelorder(root *TreeNode) [][]int {
// Time complexity: O(n)
// Spatial complexity: O(n)
res := [][]int{}
var bfs func(node *TreeNode, dep int)
bfs = func(node *TreeNode, dep int) {
if node == nil {
return
}
if len(res) == dep {
res = append(res, []int{})
}
res[dep] = append(res[dep], node.Val)
bfs(node.Left, dep+1)
bfs(node.Right, dep+1)
}
bfs(root, 0)
return res
}
// Iterate
func levelorder(root *TreeNode) [][]int {
// Time complexity: O(n)
// Spatial complexity: O(n)
if root == nil {
return [][]int{}
}
res := make([][]int, 0)
curr := []*TreeNode{root}
for len(curr) > 0 {
next := []*TreeNode{}
vals := []int{}
for _, node := range curr {
vals = append(vals, node.Val) // add curr level node val
if node.Left != nil {
next = append(next, node.Left)
}
if node.Right != nil {
next = append(next, node.Right)
}
}
res = append(res, vals)
curr = next
}
return res
}