Skip to main content

Tree Boundary Traversal

Problem Statement:​

Given a Binary Tree, find its Boundary Traversal. The traversal should be in the following order:

  1. Left Boundary:Β This includes all the nodes on the path from the root to the leftmost leaf node. You must prefer the left child over the right child when traversing. Do not include leaf nodes in this section.
  2. Leaf Nodes:Β All leaf nodes, in left-to-right order, that are not part of the left or right boundary.
  3. Reverse Right Boundary:Β This includes all the nodes on the path from the rightmost leaf node to the root, traversed in reverse order. You must prefer the right child over the left child when traversing. Do not include the root in this section if it was already included in the left boundary.

Note: If the root doesn't have a left subtree or right subtree, then the root itself is the left or right boundary.

Input: root[] = [1, 2, 3, 4, 5, 6, 7, N, N, 8, 9, N, N, N, N]
Output:[1, 2, 4, 8, 9, 6, 7, 3]
Explanation:

  • Example:



βœ… Solution: Boundary Traversal (Left + Leaves + Right)​

class Solution {
public:
bool isLeaf(Node *root) {
return !root->left && !root->right;
}

void addLeftBoundary(Node *root, vector<int> &res) {
Node *curr = root->left;
while(curr) {
if(!isLeaf(curr)) res.push_back(curr->data);
if(curr->left) curr = curr->left;
else curr = curr->right;
}
}

void addLeaves(Node *root, vector<int> &res) {
if(root == NULL) return;
if(isLeaf(root)) {
res.push_back(root->data);
return;
}
addLeaves(root->left, res);
addLeaves(root->right, res);
}

void addRightBoundary(Node *root, vector<int> &res) {
Node *curr = root->right;
vector<int> temp;
while(curr) {
if(!isLeaf(curr)) temp.push_back(curr->data);
if(curr->right) curr = curr->right;
else curr = curr->left; // ⚠️ fix: missing assignment!
}
// Reverse and add to result
res.insert(res.end(), temp.rbegin(), temp.rend());
}

vector<int> boundaryTraversal(Node *root) {
vector<int> res;
if(root == NULL) return res;

if(!isLeaf(root)) res.push_back(root->data); // Include root if not leaf
addLeftBoundary(root, res);
addLeaves(root, res);
addRightBoundary(root, res);

return res;
}
};


πŸ“ How It Works​

  • The boundary traversal involves visiting:
    1. Left boundary (excluding leaves)
    2. All leaf nodes (from left to right)
    3. Right boundary (excluding leaves, in reverse)
  • To avoid duplicates, we:
    • Skip leaves while adding left/right boundary.
    • Add all leaves separately.
    • Root is only added if it's not a leaf.

🧩 Key Observations​

  • Left boundary is top-down, right boundary is bottom-up.
  • Leaf nodes may be part of both sides, so we extract them in a separate pass.

⏱️ Time & Space Complexity​

MetricValue
⏱️ Time ComplexityO(N) – visit each node at most once
πŸͺ„ Space ComplexityO(H) – due to recursion for leaves (H = height)

⚠️ Edge Cases​

  • βœ… Tree with only root β†’ add root once
  • βœ… Tree with only left or right subtree β†’ still works
  • βœ… All nodes are leaves β†’ all nodes added only once

⚠️ Bug Fix: In this line inside addRightBoundary:

else curr->left;  // ❌ missing assignment

Should be:

else curr = curr->left;  // βœ… corrected


πŸ’‘ Other Approaches​

ApproachNotes
BFS with boundary taggingComplex to avoid duplicates
DFS with levels and taggingNot efficient for boundary traversal


πŸš€ Level Up Your Engineering Mindset

Never Study in Isolation. Join Binary Dose.

Connect with fellow engineers, clear conceptual doubts, and get 2 visual breakdowns & engineering mental models daily across our community channels.

Discord
Official Hub

Discord Community

Start at #welcome-and-rules, say hello in #general-chat, clear doubts, and collaborate with engineers worldwide.

Join Discord Server→
⚑
Daily Knowledge Drops

Daily Visual Deep-Dives

Bite-sized system design schematics, core OS internals, and DSA intuition served right into your feeds every single day.

πŸ’‘Have handwritten notes, cheat-sheets, or want to publish a technical article?
Learn How to Contribute→