Boundary Traversal of Binary Tree in DSA Go - Time & Space Complexity
We want to understand how the time needed to do a boundary traversal of a binary tree changes as the tree grows.
Specifically, we ask: How many steps does it take to visit the boundary nodes of the tree?
Analyze the time complexity of the following code snippet.
func boundaryTraversal(root *Node) []int {
if root == nil {
return []int{}
}
res := []int{root.data}
addLeftBoundary(root.left, &res)
addLeaves(root.left, &res)
addLeaves(root.right, &res)
addRightBoundary(root.right, &res)
return res
}
// Helper functions traverse parts of the tree
This code collects the boundary nodes of a binary tree in anti-clockwise order.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Traversing nodes in the left boundary, leaves, and right boundary.
- How many times: Each node is visited a constant number of times (at most twice) during these traversals.
As the number of nodes (n) in the tree grows, the traversal visits each node a constant number of times.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 visits |
| 100 | About 100 visits |
| 1000 | About 1000 visits |
Pattern observation: The number of steps grows roughly in direct proportion to the number of nodes.
Time Complexity: O(n)
This means the time to do the boundary traversal grows linearly with the number of nodes in the tree.
[X] Wrong: "Boundary traversal takes more than linear time because it does multiple traversals."
[OK] Correct: Although it looks like multiple passes, each node is visited only a constant number of times in total, so the overall time is still linear.
Understanding this helps you explain how tree traversals work efficiently and shows you can analyze combined traversals clearly.
"What if the tree is skewed (like a linked list)? How would the time complexity change?"
Practice
Boundary Traversal in a binary tree?Solution
Step 1: Understand boundary traversal definition
Boundary traversal prints nodes on the edges of the tree, including left boundary, leaves, and right boundary.Step 2: Compare with other traversals
Unlike leaf-only or level order, boundary traversal covers all edges in anti-clockwise order.Final Answer:
To print all nodes on the boundary of the tree in an anti-clockwise direction -> Option DQuick Check:
Boundary traversal = print edges anti-clockwise [OK]
- Confusing boundary traversal with leaf node traversal
- Thinking it prints nodes level-wise
- Mixing it with in-order traversal
Solution
Step 1: Understand function input and output
The function should take a pointer to the root node and return a slice of integers representing node values.Step 2: Check each option
func boundaryTraversal(root *Node) []int matches input as pointer and output as slice of int, suitable for traversal results.Final Answer:
func boundaryTraversal(root *Node) []int -> Option BQuick Check:
Pointer input + slice output = correct signature [OK]
- Passing node by value instead of pointer
- Returning single int instead of slice
- Returning slice of nodes instead of values
func main() {
root := &Node{1, nil, nil}
root.Left = &Node{2, nil, nil}
root.Right = &Node{3, nil, nil}
root.Left.Left = &Node{4, nil, nil}
root.Left.Right = &Node{5, nil, nil}
root.Right.Right = &Node{6, nil, nil}
root.Left.Right.Left = &Node{7, nil, nil}
root.Left.Right.Right = &Node{8, nil, nil}
root.Right.Right.Left = &Node{9, nil, nil}
result := boundaryTraversal(root)
fmt.Println(result)
}Solution
Step 1: Identify boundary nodes in anti-clockwise order
Left boundary: 1, 2, 4 (excluding leaves repeated), Leaves: 4,7,8,9,6, Right boundary: 3 (excluding leaf 6 as it's already included)Step 2: Combine nodes without duplicates
Boundary traversal = 1 (root), 2 (left boundary), 4 (leaf), 7 (leaf), 8 (leaf), 9 (leaf), 6 (leaf), 3 (right boundary)Final Answer:
[1 2 4 7 8 9 6 3] -> Option AQuick Check:
Boundary nodes combined = [1 2 4 7 8 9 6 3] [OK]
- Including internal nodes like 5 in boundary
- Repeating leaf nodes in boundary and leaves
- Wrong order of right boundary nodes
func boundaryTraversal(root *Node) []int {
if root == nil {
return []int{}
}
result := []int{root.Val}
addLeftBoundary(root.Left, &result)
addLeaves(root, &result)
addRightBoundary(root.Right, &result)
return result
}
func addLeftBoundary(node *Node, res *[]int) {
for node != nil {
if node.Left != nil || node.Right != nil {
*res = append(*res, node.Val)
}
if node.Left != nil {
node = node.Left
} else {
node = node.Right
}
}
}
func addLeaves(node *Node, res *[]int) {
if node == nil {
return
}
if node.Left == nil && node.Right == nil {
*res = append(*res, node.Val)
return
}
addLeaves(node.Left, res)
addLeaves(node.Right, res)
}
func addRightBoundary(node *Node, res *[]int) {
temp := []int{}
for node != nil {
if node.Left != nil || node.Right != nil {
temp = append(temp, node.Val)
}
if node.Right != nil {
node = node.Right
} else {
node = node.Left
}
}
for i := len(temp) - 1; i >= 0; i-- {
*res = append(*res, temp[i])
}
}Solution
Step 1: Analyze addLeftBoundary function
It adds nodes if they have left or right child, but does not exclude leaf nodes properly, so leaf nodes may be added twice.Step 2: Check leaf node addition
Leaves are added separately by addLeaves, so left boundary should exclude leaves to avoid duplicates.Final Answer:
Left boundary includes leaf nodes which should be excluded -> Option CQuick Check:
Left boundary must exclude leaves [OK]
- Not excluding leaves in left boundary
- Appending right boundary in forward order
- Forgetting to add root node
Solution
Step 1: Understand clockwise boundary traversal order
Clockwise order starts from root, then right boundary top-down, leaves right-to-left, and left boundary bottom-up.Step 2: Match options with traversal order
Traverse right boundary top-down, then leaves right-to-left, then left boundary bottom-up matches this order exactly, others do not.Final Answer:
Traverse right boundary top-down, then leaves right-to-left, then left boundary bottom-up -> Option AQuick Check:
Clockwise = root, right boundary, leaves, left boundary [OK]
- Using left boundary first for clockwise
- Not reversing leaf order for clockwise
- Mixing top-down and bottom-up incorrectly
Ready to prove it?
Pass the test and this pattern moves unknown
